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

Side by Side Diff: runtime/vm/intermediate_language_x64.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
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 11 matching lines...) Expand all
22 22
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, throw_on_javascript_int_overflow); 25 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
26 DECLARE_FLAG(bool, use_osr); 26 DECLARE_FLAG(bool, use_osr);
27 27
28 // Generic summary for call instructions that have all arguments pushed 28 // Generic summary for call instructions that have all arguments pushed
29 // on the stack and return the result in a fixed register RAX. 29 // on the stack and return the result in a fixed register RAX.
30 LocationSummary* Instruction::MakeCallSummary() { 30 LocationSummary* Instruction::MakeCallSummary() {
31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
32 result->set_out(Location::RegisterLocation(RAX)); 32 result->set_out(0, Location::RegisterLocation(RAX));
33 return result; 33 return result;
34 } 34 }
35 35
36 36
37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { 37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const {
38 const intptr_t kNumInputs = 1; 38 const intptr_t kNumInputs = 1;
39 const intptr_t kNumTemps= 0; 39 const intptr_t kNumTemps= 0;
40 LocationSummary* locs = 40 LocationSummary* locs =
41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
42 locs->set_in(0, Location::AnyOrConstant(value())); 42 locs->set_in(0, Location::AnyOrConstant(value()));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 // Detect pattern when one value is zero and another is a power of 2. 117 // Detect pattern when one value is zero and another is a power of 2.
118 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { 118 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) {
119 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || 119 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) ||
120 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); 120 (Utils::IsPowerOfTwo(v2) && (v1 == 0));
121 } 121 }
122 122
123 123
124 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { 124 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const {
125 comparison()->InitializeLocationSummary(opt); 125 comparison()->InitializeLocationSummary(opt);
126 // TODO(vegorov): support byte register constraints in the register allocator. 126 // TODO(vegorov): support byte register constraints in the register allocator.
127 comparison()->locs()->set_out(Location::RegisterLocation(RDX)); 127 comparison()->locs()->set_out(0, Location::RegisterLocation(RDX));
128 return comparison()->locs(); 128 return comparison()->locs();
129 } 129 }
130 130
131 131
132 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 132 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
133 ASSERT(locs()->out().reg() == RDX); 133 ASSERT(locs()->out(0).reg() == RDX);
134 134
135 // Clear upper part of the out register. We are going to use setcc on it 135 // Clear upper part of the out register. We are going to use setcc on it
136 // which is a byte move. 136 // which is a byte move.
137 __ xorq(RDX, RDX); 137 __ xorq(RDX, RDX);
138 138
139 // Emit comparison code. This must not overwrite the result register. 139 // Emit comparison code. This must not overwrite the result register.
140 BranchLabels labels = { NULL, NULL, NULL }; 140 BranchLabels labels = { NULL, NULL, NULL };
141 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels); 141 Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
142 142
143 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_); 143 const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { 198 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
199 const intptr_t kNumInputs = 1; 199 const intptr_t kNumInputs = 1;
200 return LocationSummary::Make(kNumInputs, 200 return LocationSummary::Make(kNumInputs,
201 Location::SameAsFirstInput(), 201 Location::SameAsFirstInput(),
202 LocationSummary::kNoCall); 202 LocationSummary::kNoCall);
203 } 203 }
204 204
205 205
206 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 206 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
207 Register value = locs()->in(0).reg(); 207 Register value = locs()->in(0).reg();
208 Register result = locs()->out().reg(); 208 Register result = locs()->out(0).reg();
209 ASSERT(result == value); // Assert that register assignment is correct. 209 ASSERT(result == value); // Assert that register assignment is correct.
210 __ movq(Address(RBP, local().index() * kWordSize), value); 210 __ movq(Address(RBP, local().index() * kWordSize), value);
211 } 211 }
212 212
213 213
214 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { 214 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
215 const intptr_t kNumInputs = 0; 215 const intptr_t kNumInputs = 0;
216 return LocationSummary::Make(kNumInputs, 216 return LocationSummary::Make(kNumInputs,
217 Location::RequiresRegister(), 217 Location::RequiresRegister(),
218 LocationSummary::kNoCall); 218 LocationSummary::kNoCall);
219 } 219 }
220 220
221 221
222 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 222 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
223 // The register allocator drops constant definitions that have no uses. 223 // The register allocator drops constant definitions that have no uses.
224 if (!locs()->out().IsInvalid()) { 224 if (!locs()->out(0).IsInvalid()) {
225 Register result = locs()->out().reg(); 225 Register result = locs()->out(0).reg();
226 __ LoadObject(result, value(), PP); 226 __ LoadObject(result, value(), PP);
227 } 227 }
228 } 228 }
229 229
230 230
231 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { 231 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
232 const intptr_t kNumInputs = 3; 232 const intptr_t kNumInputs = 3;
233 const intptr_t kNumTemps = 0; 233 const intptr_t kNumTemps = 0;
234 LocationSummary* summary = 234 LocationSummary* summary =
235 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 235 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
236 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. 236 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
237 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. 237 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator.
238 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. 238 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments.
239 summary->set_out(Location::RegisterLocation(RAX)); 239 summary->set_out(0, Location::RegisterLocation(RAX));
240 return summary; 240 return summary;
241 } 241 }
242 242
243 243
244 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { 244 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const {
245 const intptr_t kNumInputs = 1; 245 const intptr_t kNumInputs = 1;
246 const intptr_t kNumTemps = 0; 246 const intptr_t kNumTemps = 0;
247 LocationSummary* locs = 247 LocationSummary* locs =
248 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 248 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
249 locs->set_in(0, Location::RegisterLocation(RAX)); 249 locs->set_in(0, Location::RegisterLocation(RAX));
250 locs->set_out(Location::RegisterLocation(RAX)); 250 locs->set_out(0, Location::RegisterLocation(RAX));
251 return locs; 251 return locs;
252 } 252 }
253 253
254 254
255 static void EmitAssertBoolean(Register reg, 255 static void EmitAssertBoolean(Register reg,
256 intptr_t token_pos, 256 intptr_t token_pos,
257 intptr_t deopt_id, 257 intptr_t deopt_id,
258 LocationSummary* locs, 258 LocationSummary* locs,
259 FlowGraphCompiler* compiler) { 259 FlowGraphCompiler* compiler) {
260 // Check that the type of the value is allowed in conditional context. 260 // Check that the type of the value is allowed in conditional context.
(...skipping 12 matching lines...) Expand all
273 1, 273 1,
274 locs); 274 locs);
275 // We should never return here. 275 // We should never return here.
276 __ int3(); 276 __ int3();
277 __ Bind(&done); 277 __ Bind(&done);
278 } 278 }
279 279
280 280
281 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 281 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
282 Register obj = locs()->in(0).reg(); 282 Register obj = locs()->in(0).reg();
283 Register result = locs()->out().reg(); 283 Register result = locs()->out(0).reg();
284 284
285 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 285 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
286 ASSERT(obj == result); 286 ASSERT(obj == result);
287 } 287 }
288 288
289 289
290 static Condition TokenKindToSmiCondition(Token::Kind kind) { 290 static Condition TokenKindToSmiCondition(Token::Kind kind) {
291 switch (kind) { 291 switch (kind) {
292 case Token::kEQ: return EQUAL; 292 case Token::kEQ: return EQUAL;
293 case Token::kNE: return NOT_EQUAL; 293 case Token::kNE: return NOT_EQUAL;
294 case Token::kLT: return LESS; 294 case Token::kLT: return LESS;
295 case Token::kGT: return GREATER; 295 case Token::kGT: return GREATER;
296 case Token::kLTE: return LESS_EQUAL; 296 case Token::kLTE: return LESS_EQUAL;
297 case Token::kGTE: return GREATER_EQUAL; 297 case Token::kGTE: return GREATER_EQUAL;
298 default: 298 default:
299 UNREACHABLE(); 299 UNREACHABLE();
300 return OVERFLOW; 300 return OVERFLOW;
301 } 301 }
302 } 302 }
303 303
304 304
305 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { 305 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const {
306 const intptr_t kNumInputs = 2; 306 const intptr_t kNumInputs = 2;
307 if (operation_cid() == kDoubleCid) { 307 if (operation_cid() == kDoubleCid) {
308 const intptr_t kNumTemps = 0; 308 const intptr_t kNumTemps = 0;
309 LocationSummary* locs = 309 LocationSummary* locs =
310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
311 locs->set_in(0, Location::RequiresFpuRegister()); 311 locs->set_in(0, Location::RequiresFpuRegister());
312 locs->set_in(1, Location::RequiresFpuRegister()); 312 locs->set_in(1, Location::RequiresFpuRegister());
313 locs->set_out(Location::RequiresRegister()); 313 locs->set_out(0, Location::RequiresRegister());
314 return locs; 314 return locs;
315 } 315 }
316 if (operation_cid() == kSmiCid) { 316 if (operation_cid() == kSmiCid) {
317 const intptr_t kNumTemps = 0; 317 const intptr_t kNumTemps = 0;
318 LocationSummary* locs = 318 LocationSummary* locs =
319 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 319 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
320 locs->set_in(0, Location::RegisterOrConstant(left())); 320 locs->set_in(0, Location::RegisterOrConstant(left()));
321 // Only one input can be a constant operand. The case of two constant 321 // Only one input can be a constant operand. The case of two constant
322 // operands should be handled by constant propagation. 322 // operands should be handled by constant propagation.
323 // Only right can be a stack slot. 323 // Only right can be a stack slot.
324 locs->set_in(1, locs->in(0).IsConstant() 324 locs->set_in(1, locs->in(0).IsConstant()
325 ? Location::RequiresRegister() 325 ? Location::RequiresRegister()
326 : Location::RegisterOrConstant(right())); 326 : Location::RegisterOrConstant(right()));
327 locs->set_out(Location::RequiresRegister()); 327 locs->set_out(0, Location::RequiresRegister());
328 return locs; 328 return locs;
329 } 329 }
330 UNREACHABLE(); 330 UNREACHABLE();
331 return NULL; 331 return NULL;
332 } 332 }
333 333
334 334
335 static void LoadValueCid(FlowGraphCompiler* compiler, 335 static void LoadValueCid(FlowGraphCompiler* compiler,
336 Register value_cid_reg, 336 Register value_cid_reg,
337 Register value_reg, 337 Register value_reg,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 457
458 458
459 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 459 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
460 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 460 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
461 461
462 Label is_true, is_false; 462 Label is_true, is_false;
463 BranchLabels labels = { &is_true, &is_false, &is_false }; 463 BranchLabels labels = { &is_true, &is_false, &is_false };
464 Condition true_condition = EmitComparisonCode(compiler, labels); 464 Condition true_condition = EmitComparisonCode(compiler, labels);
465 EmitBranchOnCondition(compiler, true_condition, labels); 465 EmitBranchOnCondition(compiler, true_condition, labels);
466 466
467 Register result = locs()->out().reg(); 467 Register result = locs()->out(0).reg();
468 Label done; 468 Label done;
469 __ Bind(&is_false); 469 __ Bind(&is_false);
470 __ LoadObject(result, Bool::False(), PP); 470 __ LoadObject(result, Bool::False(), PP);
471 __ jmp(&done); 471 __ jmp(&done);
472 __ Bind(&is_true); 472 __ Bind(&is_true);
473 __ LoadObject(result, Bool::True(), PP); 473 __ LoadObject(result, Bool::True(), PP);
474 __ Bind(&done); 474 __ Bind(&done);
475 } 475 }
476 476
477 477
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 530
531 531
532 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const { 532 LocationSummary* RelationalOpInstr::MakeLocationSummary(bool opt) const {
533 const intptr_t kNumInputs = 2; 533 const intptr_t kNumInputs = 2;
534 const intptr_t kNumTemps = 0; 534 const intptr_t kNumTemps = 0;
535 if (operation_cid() == kDoubleCid) { 535 if (operation_cid() == kDoubleCid) {
536 LocationSummary* summary = 536 LocationSummary* summary =
537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
538 summary->set_in(0, Location::RequiresFpuRegister()); 538 summary->set_in(0, Location::RequiresFpuRegister());
539 summary->set_in(1, Location::RequiresFpuRegister()); 539 summary->set_in(1, Location::RequiresFpuRegister());
540 summary->set_out(Location::RequiresRegister()); 540 summary->set_out(0, Location::RequiresRegister());
541 return summary; 541 return summary;
542 } 542 }
543 ASSERT(operation_cid() == kSmiCid); 543 ASSERT(operation_cid() == kSmiCid);
544 LocationSummary* summary = 544 LocationSummary* summary =
545 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 545 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
546 summary->set_in(0, Location::RegisterOrConstant(left())); 546 summary->set_in(0, Location::RegisterOrConstant(left()));
547 // Only one input can be a constant operand. The case of two constant 547 // Only one input can be a constant operand. The case of two constant
548 // operands should be handled by constant propagation. 548 // operands should be handled by constant propagation.
549 summary->set_in(1, summary->in(0).IsConstant() 549 summary->set_in(1, summary->in(0).IsConstant()
550 ? Location::RequiresRegister() 550 ? Location::RequiresRegister()
551 : Location::RegisterOrConstant(right())); 551 : Location::RegisterOrConstant(right()));
552 summary->set_out(Location::RequiresRegister()); 552 summary->set_out(0, Location::RequiresRegister());
553 return summary; 553 return summary;
554 } 554 }
555 555
556 556
557 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 557 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
558 BranchLabels labels) { 558 BranchLabels labels) {
559 if (operation_cid() == kSmiCid) { 559 if (operation_cid() == kSmiCid) {
560 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 560 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
561 } else { 561 } else {
562 ASSERT(operation_cid() == kDoubleCid); 562 ASSERT(operation_cid() == kDoubleCid);
563 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 563 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
564 } 564 }
565 } 565 }
566 566
567 567
568 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 568 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
569 Label is_true, is_false; 569 Label is_true, is_false;
570 BranchLabels labels = { &is_true, &is_false, &is_false }; 570 BranchLabels labels = { &is_true, &is_false, &is_false };
571 Condition true_condition = EmitComparisonCode(compiler, labels); 571 Condition true_condition = EmitComparisonCode(compiler, labels);
572 EmitBranchOnCondition(compiler, true_condition, labels); 572 EmitBranchOnCondition(compiler, true_condition, labels);
573 573
574 Register result = locs()->out().reg(); 574 Register result = locs()->out(0).reg();
575 Label done; 575 Label done;
576 __ Bind(&is_false); 576 __ Bind(&is_false);
577 __ LoadObject(result, Bool::False(), PP); 577 __ LoadObject(result, Bool::False(), PP);
578 __ jmp(&done); 578 __ jmp(&done);
579 __ Bind(&is_true); 579 __ Bind(&is_true);
580 __ LoadObject(result, Bool::True(), PP); 580 __ LoadObject(result, Bool::True(), PP);
581 __ Bind(&done); 581 __ Bind(&done);
582 } 582 }
583 583
584 584
585 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 585 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
586 BranchInstr* branch) { 586 BranchInstr* branch) {
587 BranchLabels labels = compiler->CreateBranchLabels(branch); 587 BranchLabels labels = compiler->CreateBranchLabels(branch);
588 Condition true_condition = EmitComparisonCode(compiler, labels); 588 Condition true_condition = EmitComparisonCode(compiler, labels);
589 EmitBranchOnCondition(compiler, true_condition, labels); 589 EmitBranchOnCondition(compiler, true_condition, labels);
590 } 590 }
591 591
592 592
593 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { 593 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
594 const intptr_t kNumInputs = 0; 594 const intptr_t kNumInputs = 0;
595 const intptr_t kNumTemps = 3; 595 const intptr_t kNumTemps = 3;
596 LocationSummary* locs = 596 LocationSummary* locs =
597 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 597 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
598 locs->set_temp(0, Location::RegisterLocation(RAX)); 598 locs->set_temp(0, Location::RegisterLocation(RAX));
599 locs->set_temp(1, Location::RegisterLocation(RBX)); 599 locs->set_temp(1, Location::RegisterLocation(RBX));
600 locs->set_temp(2, Location::RegisterLocation(R10)); 600 locs->set_temp(2, Location::RegisterLocation(R10));
601 locs->set_out(Location::RegisterLocation(RAX)); 601 locs->set_out(0, Location::RegisterLocation(RAX));
602 return locs; 602 return locs;
603 } 603 }
604 604
605 605
606 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 606 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
607 ASSERT(locs()->temp(0).reg() == RAX); 607 ASSERT(locs()->temp(0).reg() == RAX);
608 ASSERT(locs()->temp(1).reg() == RBX); 608 ASSERT(locs()->temp(1).reg() == RBX);
609 ASSERT(locs()->temp(2).reg() == R10); 609 ASSERT(locs()->temp(2).reg() == R10);
610 Register result = locs()->out().reg(); 610 Register result = locs()->out(0).reg();
611 611
612 // Push the result place holder initialized to NULL. 612 // Push the result place holder initialized to NULL.
613 __ PushObject(Object::ZoneHandle(), PP); 613 __ PushObject(Object::ZoneHandle(), PP);
614 // Pass a pointer to the first argument in RAX. 614 // Pass a pointer to the first argument in RAX.
615 if (!function().HasOptionalParameters()) { 615 if (!function().HasOptionalParameters()) {
616 __ leaq(RAX, Address(RBP, (kParamEndSlotFromFp + 616 __ leaq(RAX, Address(RBP, (kParamEndSlotFromFp +
617 function().NumParameters()) * kWordSize)); 617 function().NumParameters()) * kWordSize));
618 } else { 618 } else {
619 __ leaq(RAX, 619 __ leaq(RAX,
620 Address(RBP, kFirstLocalSlotFromFp * kWordSize)); 620 Address(RBP, kFirstLocalSlotFromFp * kWordSize));
(...skipping 29 matching lines...) Expand all
650 const intptr_t kNumInputs = 1; 650 const intptr_t kNumInputs = 1;
651 // TODO(fschneider): Allow immediate operands for the char code. 651 // TODO(fschneider): Allow immediate operands for the char code.
652 return LocationSummary::Make(kNumInputs, 652 return LocationSummary::Make(kNumInputs,
653 Location::RequiresRegister(), 653 Location::RequiresRegister(),
654 LocationSummary::kNoCall); 654 LocationSummary::kNoCall);
655 } 655 }
656 656
657 657
658 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 658 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
659 Register char_code = locs()->in(0).reg(); 659 Register char_code = locs()->in(0).reg();
660 Register result = locs()->out().reg(); 660 Register result = locs()->out(0).reg();
661 __ LoadImmediate(result, 661 __ LoadImmediate(result,
662 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())), PP); 662 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())), PP);
663 __ movq(result, Address(result, 663 __ movq(result, Address(result,
664 char_code, 664 char_code,
665 TIMES_HALF_WORD_SIZE, // Char code is a smi. 665 TIMES_HALF_WORD_SIZE, // Char code is a smi.
666 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 666 Symbols::kNullCharCodeSymbolOffset * kWordSize));
667 } 667 }
668 668
669 669
670 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { 670 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const {
671 const intptr_t kNumInputs = 1; 671 const intptr_t kNumInputs = 1;
672 return LocationSummary::Make(kNumInputs, 672 return LocationSummary::Make(kNumInputs,
673 Location::RequiresRegister(), 673 Location::RequiresRegister(),
674 LocationSummary::kNoCall); 674 LocationSummary::kNoCall);
675 } 675 }
676 676
677 677
678 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 678 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
679 ASSERT(cid_ == kOneByteStringCid); 679 ASSERT(cid_ == kOneByteStringCid);
680 Register str = locs()->in(0).reg(); 680 Register str = locs()->in(0).reg();
681 Register result = locs()->out().reg(); 681 Register result = locs()->out(0).reg();
682 Label is_one, done; 682 Label is_one, done;
683 __ movq(result, FieldAddress(str, String::length_offset())); 683 __ movq(result, FieldAddress(str, String::length_offset()));
684 __ cmpq(result, Immediate(Smi::RawValue(1))); 684 __ cmpq(result, Immediate(Smi::RawValue(1)));
685 __ j(EQUAL, &is_one, Assembler::kNearJump); 685 __ j(EQUAL, &is_one, Assembler::kNearJump);
686 __ movq(result, Immediate(Smi::RawValue(-1))); 686 __ movq(result, Immediate(Smi::RawValue(-1)));
687 __ jmp(&done); 687 __ jmp(&done);
688 __ Bind(&is_one); 688 __ Bind(&is_one);
689 __ movzxb(result, FieldAddress(str, OneByteString::data_offset())); 689 __ movzxb(result, FieldAddress(str, OneByteString::data_offset()));
690 __ SmiTag(result); 690 __ SmiTag(result);
691 __ Bind(&done); 691 __ Bind(&done);
692 } 692 }
693 693
694 694
695 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { 695 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const {
696 const intptr_t kNumInputs = 1; 696 const intptr_t kNumInputs = 1;
697 const intptr_t kNumTemps = 0; 697 const intptr_t kNumTemps = 0;
698 LocationSummary* summary = 698 LocationSummary* summary =
699 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 699 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
700 summary->set_in(0, Location::RegisterLocation(RAX)); 700 summary->set_in(0, Location::RegisterLocation(RAX));
701 summary->set_out(Location::RegisterLocation(RAX)); 701 summary->set_out(0, Location::RegisterLocation(RAX));
702 return summary; 702 return summary;
703 } 703 }
704 704
705 705
706 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 706 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
707 Register array = locs()->in(0).reg(); 707 Register array = locs()->in(0).reg();
708 __ pushq(array); 708 __ pushq(array);
709 const int kNumberOfArguments = 1; 709 const int kNumberOfArguments = 1;
710 const Array& kNoArgumentNames = Object::null_array(); 710 const Array& kNoArgumentNames = Object::null_array();
711 compiler->GenerateStaticCall(deopt_id(), 711 compiler->GenerateStaticCall(deopt_id(),
712 token_pos(), 712 token_pos(),
713 CallFunction(), 713 CallFunction(),
714 kNumberOfArguments, 714 kNumberOfArguments,
715 kNoArgumentNames, 715 kNoArgumentNames,
716 locs()); 716 locs());
717 ASSERT(locs()->out().reg() == RAX); 717 ASSERT(locs()->out(0).reg() == RAX);
718 } 718 }
719 719
720 720
721 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { 721 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const {
722 const intptr_t kNumInputs = 1; 722 const intptr_t kNumInputs = 1;
723 return LocationSummary::Make(kNumInputs, 723 return LocationSummary::Make(kNumInputs,
724 Location::RequiresRegister(), 724 Location::RequiresRegister(),
725 LocationSummary::kNoCall); 725 LocationSummary::kNoCall);
726 } 726 }
727 727
728 728
729 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 729 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
730 Register object = locs()->in(0).reg(); 730 Register object = locs()->in(0).reg();
731 Register result = locs()->out().reg(); 731 Register result = locs()->out(0).reg();
732 __ movq(result, FieldAddress(object, offset())); 732 __ movq(result, FieldAddress(object, offset()));
733 } 733 }
734 734
735 735
736 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { 736 LocationSummary* LoadClassIdInstr::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 LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 744 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
745 Register object = locs()->in(0).reg(); 745 Register object = locs()->in(0).reg();
746 Register result = locs()->out().reg(); 746 Register result = locs()->out(0).reg();
747 Label load, done; 747 Label load, done;
748 __ testq(object, Immediate(kSmiTagMask)); 748 __ testq(object, Immediate(kSmiTagMask));
749 __ j(NOT_ZERO, &load, Assembler::kNearJump); 749 __ j(NOT_ZERO, &load, Assembler::kNearJump);
750 __ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)), PP); 750 __ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)), PP);
751 __ jmp(&done); 751 __ jmp(&done);
752 __ Bind(&load); 752 __ Bind(&load);
753 __ LoadClassId(result, object); 753 __ LoadClassId(result, object);
754 __ SmiTag(result); 754 __ SmiTag(result);
755 __ Bind(&done); 755 __ Bind(&done);
756 } 756 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 } else { 840 } else {
841 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 841 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
842 ? Location::Constant( 842 ? Location::Constant(
843 index()->definition()->AsConstant()->value()) 843 index()->definition()->AsConstant()->value())
844 : Location::RequiresRegister()); 844 : Location::RequiresRegister());
845 } 845 }
846 if ((representation() == kUnboxedDouble) || 846 if ((representation() == kUnboxedDouble) ||
847 (representation() == kUnboxedFloat32x4) || 847 (representation() == kUnboxedFloat32x4) ||
848 (representation() == kUnboxedInt32x4) || 848 (representation() == kUnboxedInt32x4) ||
849 (representation() == kUnboxedFloat64x2)) { 849 (representation() == kUnboxedFloat64x2)) {
850 locs->set_out(Location::RequiresFpuRegister()); 850 locs->set_out(0, Location::RequiresFpuRegister());
851 } else { 851 } else {
852 locs->set_out(Location::RequiresRegister()); 852 locs->set_out(0, Location::RequiresRegister());
853 } 853 }
854 return locs; 854 return locs;
855 } 855 }
856 856
857 857
858 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 858 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
859 Register array = locs()->in(0).reg(); 859 Register array = locs()->in(0).reg();
860 Location index = locs()->in(1); 860 Location index = locs()->in(1);
861 861
862 const bool is_external = 862 const bool is_external =
(...skipping 17 matching lines...) Expand all
880 } 880 }
881 881
882 if ((representation() == kUnboxedDouble) || 882 if ((representation() == kUnboxedDouble) ||
883 (representation() == kUnboxedFloat32x4) || 883 (representation() == kUnboxedFloat32x4) ||
884 (representation() == kUnboxedInt32x4) || 884 (representation() == kUnboxedInt32x4) ||
885 (representation() == kUnboxedFloat64x2)) { 885 (representation() == kUnboxedFloat64x2)) {
886 if ((index_scale() == 1) && index.IsRegister()) { 886 if ((index_scale() == 1) && index.IsRegister()) {
887 __ SmiUntag(index.reg()); 887 __ SmiUntag(index.reg());
888 } 888 }
889 889
890 XmmRegister result = locs()->out().fpu_reg(); 890 XmmRegister result = locs()->out(0).fpu_reg();
891 if (class_id() == kTypedDataFloat32ArrayCid) { 891 if (class_id() == kTypedDataFloat32ArrayCid) {
892 // Load single precision float. 892 // Load single precision float.
893 __ movss(result, element_address); 893 __ movss(result, element_address);
894 } else if (class_id() == kTypedDataFloat64ArrayCid) { 894 } else if (class_id() == kTypedDataFloat64ArrayCid) {
895 __ movsd(result, element_address); 895 __ movsd(result, element_address);
896 } else { 896 } else {
897 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) || 897 ASSERT((class_id() == kTypedDataInt32x4ArrayCid) ||
898 (class_id() == kTypedDataFloat32x4ArrayCid) || 898 (class_id() == kTypedDataFloat32x4ArrayCid) ||
899 (class_id() == kTypedDataFloat64x2ArrayCid)); 899 (class_id() == kTypedDataFloat64x2ArrayCid));
900 __ movups(result, element_address); 900 __ movups(result, element_address);
901 } 901 }
902 return; 902 return;
903 } 903 }
904 904
905 if ((index_scale() == 1) && index.IsRegister()) { 905 if ((index_scale() == 1) && index.IsRegister()) {
906 __ SmiUntag(index.reg()); 906 __ SmiUntag(index.reg());
907 } 907 }
908 Register result = locs()->out().reg(); 908 Register result = locs()->out(0).reg();
909 switch (class_id()) { 909 switch (class_id()) {
910 case kTypedDataInt8ArrayCid: 910 case kTypedDataInt8ArrayCid:
911 __ movsxb(result, element_address); 911 __ movsxb(result, element_address);
912 __ SmiTag(result); 912 __ SmiTag(result);
913 break; 913 break;
914 case kTypedDataUint8ArrayCid: 914 case kTypedDataUint8ArrayCid:
915 case kTypedDataUint8ClampedArrayCid: 915 case kTypedDataUint8ClampedArrayCid:
916 case kExternalTypedDataUint8ArrayCid: 916 case kExternalTypedDataUint8ArrayCid:
917 case kExternalTypedDataUint8ClampedArrayCid: 917 case kExternalTypedDataUint8ClampedArrayCid:
918 case kOneByteStringCid: 918 case kOneByteStringCid:
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 : instruction_(instruction), cls_(cls) { } 1500 : instruction_(instruction), cls_(cls) { }
1501 1501
1502 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1502 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1503 __ Comment("StoreInstanceFieldSlowPath"); 1503 __ Comment("StoreInstanceFieldSlowPath");
1504 __ Bind(entry_label()); 1504 __ Bind(entry_label());
1505 const Code& stub = 1505 const Code& stub =
1506 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1506 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1507 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1507 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1508 1508
1509 LocationSummary* locs = instruction_->locs(); 1509 LocationSummary* locs = instruction_->locs();
1510 locs->live_registers()->Remove(locs->out()); 1510 locs->live_registers()->Remove(locs->out(0));
1511 1511
1512 compiler->SaveLiveRegisters(locs); 1512 compiler->SaveLiveRegisters(locs);
1513 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1513 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1514 &label, 1514 &label,
1515 PcDescriptors::kOther, 1515 PcDescriptors::kOther,
1516 locs); 1516 locs);
1517 __ MoveRegister(locs->temp(0).reg(), RAX); 1517 __ MoveRegister(locs->temp(0).reg(), RAX);
1518 compiler->RestoreLiveRegisters(locs); 1518 compiler->RestoreLiveRegisters(locs);
1519 1519
1520 __ jmp(exit_label()); 1520 __ jmp(exit_label());
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 __ Bind(&skip_store); 1769 __ Bind(&skip_store);
1770 } 1770 }
1771 1771
1772 1772
1773 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { 1773 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1774 const intptr_t kNumInputs = 1; 1774 const intptr_t kNumInputs = 1;
1775 const intptr_t kNumTemps = 0; 1775 const intptr_t kNumTemps = 0;
1776 LocationSummary* summary = 1776 LocationSummary* summary =
1777 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1777 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1778 summary->set_in(0, Location::RequiresRegister()); 1778 summary->set_in(0, Location::RequiresRegister());
1779 summary->set_out(Location::RequiresRegister()); 1779 summary->set_out(0, Location::RequiresRegister());
1780 return summary; 1780 return summary;
1781 } 1781 }
1782 1782
1783 1783
1784 // When the parser is building an implicit static getter for optimization, 1784 // When the parser is building an implicit static getter for optimization,
1785 // it can generate a function body where deoptimization ids do not line up 1785 // it can generate a function body where deoptimization ids do not line up
1786 // with the unoptimized code. 1786 // with the unoptimized code.
1787 // 1787 //
1788 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1788 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1789 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1789 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1790 Register field = locs()->in(0).reg(); 1790 Register field = locs()->in(0).reg();
1791 Register result = locs()->out().reg(); 1791 Register result = locs()->out(0).reg();
1792 __ movq(result, FieldAddress(field, Field::value_offset())); 1792 __ movq(result, FieldAddress(field, Field::value_offset()));
1793 } 1793 }
1794 1794
1795 1795
1796 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { 1796 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const {
1797 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1797 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1798 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1798 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1799 : Location::RequiresRegister()); 1799 : Location::RequiresRegister());
1800 locs->set_temp(0, Location::RequiresRegister()); 1800 locs->set_temp(0, Location::RequiresRegister());
1801 return locs; 1801 return locs;
(...skipping 16 matching lines...) Expand all
1818 1818
1819 1819
1820 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { 1820 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1821 const intptr_t kNumInputs = 3; 1821 const intptr_t kNumInputs = 3;
1822 const intptr_t kNumTemps = 0; 1822 const intptr_t kNumTemps = 0;
1823 LocationSummary* summary = 1823 LocationSummary* summary =
1824 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1824 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1825 summary->set_in(0, Location::RegisterLocation(RAX)); 1825 summary->set_in(0, Location::RegisterLocation(RAX));
1826 summary->set_in(1, Location::RegisterLocation(RCX)); 1826 summary->set_in(1, Location::RegisterLocation(RCX));
1827 summary->set_in(2, Location::RegisterLocation(RDX)); 1827 summary->set_in(2, Location::RegisterLocation(RDX));
1828 summary->set_out(Location::RegisterLocation(RAX)); 1828 summary->set_out(0, Location::RegisterLocation(RAX));
1829 return summary; 1829 return summary;
1830 } 1830 }
1831 1831
1832 1832
1833 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1833 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1834 ASSERT(locs()->in(0).reg() == RAX); // Value. 1834 ASSERT(locs()->in(0).reg() == RAX); // Value.
1835 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 1835 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
1836 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 1836 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
1837 1837
1838 compiler->GenerateInstanceOf(token_pos(), 1838 compiler->GenerateInstanceOf(token_pos(),
1839 deopt_id(), 1839 deopt_id(),
1840 type(), 1840 type(),
1841 negate_result(), 1841 negate_result(),
1842 locs()); 1842 locs());
1843 ASSERT(locs()->out().reg() == RAX); 1843 ASSERT(locs()->out(0).reg() == RAX);
1844 } 1844 }
1845 1845
1846 1846
1847 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { 1847 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const {
1848 const intptr_t kNumInputs = 2; 1848 const intptr_t kNumInputs = 2;
1849 const intptr_t kNumTemps = 0; 1849 const intptr_t kNumTemps = 0;
1850 LocationSummary* locs = 1850 LocationSummary* locs =
1851 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1851 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1852 locs->set_in(0, Location::RegisterLocation(RBX)); 1852 locs->set_in(0, Location::RegisterLocation(RBX));
1853 locs->set_in(1, Location::RegisterLocation(R10)); 1853 locs->set_in(1, Location::RegisterLocation(R10));
1854 locs->set_out(Location::RegisterLocation(RAX)); 1854 locs->set_out(0, Location::RegisterLocation(RAX));
1855 return locs; 1855 return locs;
1856 } 1856 }
1857 1857
1858 1858
1859 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1859 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1860 // Allocate the array. R10 = length, RBX = element type. 1860 // Allocate the array. R10 = length, RBX = element type.
1861 ASSERT(locs()->in(0).reg() == RBX); 1861 ASSERT(locs()->in(0).reg() == RBX);
1862 ASSERT(locs()->in(1).reg() == R10); 1862 ASSERT(locs()->in(1).reg() == R10);
1863 compiler->GenerateCall(token_pos(), 1863 compiler->GenerateCall(token_pos(),
1864 &StubCode::AllocateArrayLabel(), 1864 &StubCode::AllocateArrayLabel(),
1865 PcDescriptors::kOther, 1865 PcDescriptors::kOther,
1866 locs()); 1866 locs());
1867 ASSERT(locs()->out().reg() == RAX); 1867 ASSERT(locs()->out(0).reg() == RAX);
1868 } 1868 }
1869 1869
1870 1870
1871 class BoxDoubleSlowPath : public SlowPathCode { 1871 class BoxDoubleSlowPath : public SlowPathCode {
1872 public: 1872 public:
1873 explicit BoxDoubleSlowPath(Instruction* instruction) 1873 explicit BoxDoubleSlowPath(Instruction* instruction)
1874 : instruction_(instruction) { } 1874 : instruction_(instruction) { }
1875 1875
1876 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1876 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1877 __ Comment("BoxDoubleSlowPath"); 1877 __ Comment("BoxDoubleSlowPath");
1878 __ Bind(entry_label()); 1878 __ Bind(entry_label());
1879 const Class& double_class = compiler->double_class(); 1879 const Class& double_class = compiler->double_class();
1880 const Code& stub = 1880 const Code& stub =
1881 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1881 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1882 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1882 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1883 1883
1884 LocationSummary* locs = instruction_->locs(); 1884 LocationSummary* locs = instruction_->locs();
1885 locs->live_registers()->Remove(locs->out()); 1885 locs->live_registers()->Remove(locs->out(0));
1886 1886
1887 compiler->SaveLiveRegisters(locs); 1887 compiler->SaveLiveRegisters(locs);
1888 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1888 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1889 &label, 1889 &label,
1890 PcDescriptors::kOther, 1890 PcDescriptors::kOther,
1891 locs); 1891 locs);
1892 __ MoveRegister(locs->out().reg(), RAX); 1892 __ MoveRegister(locs->out(0).reg(), RAX);
1893 compiler->RestoreLiveRegisters(locs); 1893 compiler->RestoreLiveRegisters(locs);
1894 1894
1895 __ jmp(exit_label()); 1895 __ jmp(exit_label());
1896 } 1896 }
1897 1897
1898 private: 1898 private:
1899 Instruction* instruction_; 1899 Instruction* instruction_;
1900 }; 1900 };
1901 1901
1902 1902
1903 class BoxFloat32x4SlowPath : public SlowPathCode { 1903 class BoxFloat32x4SlowPath : public SlowPathCode {
1904 public: 1904 public:
1905 explicit BoxFloat32x4SlowPath(Instruction* instruction) 1905 explicit BoxFloat32x4SlowPath(Instruction* instruction)
1906 : instruction_(instruction) { } 1906 : instruction_(instruction) { }
1907 1907
1908 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1908 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1909 __ Comment("BoxFloat32x4SlowPath"); 1909 __ Comment("BoxFloat32x4SlowPath");
1910 __ Bind(entry_label()); 1910 __ Bind(entry_label());
1911 const Class& float32x4_class = compiler->float32x4_class(); 1911 const Class& float32x4_class = compiler->float32x4_class();
1912 const Code& stub = 1912 const Code& stub =
1913 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); 1913 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
1914 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); 1914 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
1915 1915
1916 LocationSummary* locs = instruction_->locs(); 1916 LocationSummary* locs = instruction_->locs();
1917 locs->live_registers()->Remove(locs->out()); 1917 locs->live_registers()->Remove(locs->out(0));
1918 1918
1919 compiler->SaveLiveRegisters(locs); 1919 compiler->SaveLiveRegisters(locs);
1920 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1920 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1921 &label, 1921 &label,
1922 PcDescriptors::kOther, 1922 PcDescriptors::kOther,
1923 locs); 1923 locs);
1924 __ MoveRegister(locs->out().reg(), RAX); 1924 __ MoveRegister(locs->out(0).reg(), RAX);
1925 compiler->RestoreLiveRegisters(locs); 1925 compiler->RestoreLiveRegisters(locs);
1926 1926
1927 __ jmp(exit_label()); 1927 __ jmp(exit_label());
1928 } 1928 }
1929 1929
1930 private: 1930 private:
1931 Instruction* instruction_; 1931 Instruction* instruction_;
1932 }; 1932 };
1933 1933
1934 1934
1935 class BoxFloat64x2SlowPath : public SlowPathCode { 1935 class BoxFloat64x2SlowPath : public SlowPathCode {
1936 public: 1936 public:
1937 explicit BoxFloat64x2SlowPath(Instruction* instruction) 1937 explicit BoxFloat64x2SlowPath(Instruction* instruction)
1938 : instruction_(instruction) { } 1938 : instruction_(instruction) { }
1939 1939
1940 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1940 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1941 __ Comment("BoxFloat64x2SlowPath"); 1941 __ Comment("BoxFloat64x2SlowPath");
1942 __ Bind(entry_label()); 1942 __ Bind(entry_label());
1943 const Class& float64x2_class = compiler->float64x2_class(); 1943 const Class& float64x2_class = compiler->float64x2_class();
1944 const Code& stub = 1944 const Code& stub =
1945 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); 1945 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
1946 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); 1946 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
1947 1947
1948 LocationSummary* locs = instruction_->locs(); 1948 LocationSummary* locs = instruction_->locs();
1949 locs->live_registers()->Remove(locs->out()); 1949 locs->live_registers()->Remove(locs->out(0));
1950 1950
1951 compiler->SaveLiveRegisters(locs); 1951 compiler->SaveLiveRegisters(locs);
1952 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1952 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1953 &label, 1953 &label,
1954 PcDescriptors::kOther, 1954 PcDescriptors::kOther,
1955 locs); 1955 locs);
1956 __ MoveRegister(locs->out().reg(), RAX); 1956 __ MoveRegister(locs->out(0).reg(), RAX);
1957 compiler->RestoreLiveRegisters(locs); 1957 compiler->RestoreLiveRegisters(locs);
1958 1958
1959 __ jmp(exit_label()); 1959 __ jmp(exit_label());
1960 } 1960 }
1961 1961
1962 private: 1962 private:
1963 Instruction* instruction_; 1963 Instruction* instruction_;
1964 }; 1964 };
1965 1965
1966 1966
1967 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 1967 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1968 const intptr_t kNumInputs = 1; 1968 const intptr_t kNumInputs = 1;
1969 const intptr_t kNumTemps = 0; 1969 const intptr_t kNumTemps = 0;
1970 LocationSummary* locs = 1970 LocationSummary* locs =
1971 new LocationSummary( 1971 new LocationSummary(
1972 kNumInputs, kNumTemps, 1972 kNumInputs, kNumTemps,
1973 (opt && !IsPotentialUnboxedLoad()) 1973 (opt && !IsPotentialUnboxedLoad())
1974 ? LocationSummary::kNoCall 1974 ? LocationSummary::kNoCall
1975 : LocationSummary::kCallOnSlowPath); 1975 : LocationSummary::kCallOnSlowPath);
1976 1976
1977 locs->set_in(0, Location::RequiresRegister()); 1977 locs->set_in(0, Location::RequiresRegister());
1978 1978
1979 if (IsUnboxedLoad() && opt) { 1979 if (IsUnboxedLoad() && opt) {
1980 locs->AddTemp(Location::RequiresRegister()); 1980 locs->AddTemp(Location::RequiresRegister());
1981 } else if (IsPotentialUnboxedLoad()) { 1981 } else if (IsPotentialUnboxedLoad()) {
1982 locs->AddTemp(opt ? Location::RequiresFpuRegister() 1982 locs->AddTemp(opt ? Location::RequiresFpuRegister()
1983 : Location::FpuRegisterLocation(XMM1)); 1983 : Location::FpuRegisterLocation(XMM1));
1984 locs->AddTemp(Location::RequiresRegister()); 1984 locs->AddTemp(Location::RequiresRegister());
1985 } 1985 }
1986 locs->set_out(Location::RequiresRegister()); 1986 locs->set_out(0, Location::RequiresRegister());
1987 return locs; 1987 return locs;
1988 } 1988 }
1989 1989
1990 1990
1991 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1991 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1992 Register instance_reg = locs()->in(0).reg(); 1992 Register instance_reg = locs()->in(0).reg();
1993 if (IsUnboxedLoad() && compiler->is_optimizing()) { 1993 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1994 XmmRegister result = locs()->out().fpu_reg(); 1994 XmmRegister result = locs()->out(0).fpu_reg();
1995 Register temp = locs()->temp(0).reg(); 1995 Register temp = locs()->temp(0).reg();
1996 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes())); 1996 __ movq(temp, FieldAddress(instance_reg, offset_in_bytes()));
1997 intptr_t cid = field()->UnboxedFieldCid(); 1997 intptr_t cid = field()->UnboxedFieldCid();
1998 switch (cid) { 1998 switch (cid) {
1999 case kDoubleCid: 1999 case kDoubleCid:
2000 __ Comment("UnboxedDoubleLoadFieldInstr"); 2000 __ Comment("UnboxedDoubleLoadFieldInstr");
2001 __ movsd(result, FieldAddress(temp, Double::value_offset())); 2001 __ movsd(result, FieldAddress(temp, Double::value_offset()));
2002 break; 2002 break;
2003 case kFloat32x4Cid: 2003 case kFloat32x4Cid:
2004 __ Comment("UnboxedFloat32x4LoadFieldInstr"); 2004 __ Comment("UnboxedFloat32x4LoadFieldInstr");
2005 __ movups(result, FieldAddress(temp, Float32x4::value_offset())); 2005 __ movups(result, FieldAddress(temp, Float32x4::value_offset()));
2006 break; 2006 break;
2007 case kFloat64x2Cid: 2007 case kFloat64x2Cid:
2008 __ Comment("UnboxedFloat64x2LoadFieldInstr"); 2008 __ Comment("UnboxedFloat64x2LoadFieldInstr");
2009 __ movups(result, FieldAddress(temp, Float64x2::value_offset())); 2009 __ movups(result, FieldAddress(temp, Float64x2::value_offset()));
2010 break; 2010 break;
2011 default: 2011 default:
2012 UNREACHABLE(); 2012 UNREACHABLE();
2013 } 2013 }
2014 return; 2014 return;
2015 } 2015 }
2016 2016
2017 Label done; 2017 Label done;
2018 Register result = locs()->out().reg(); 2018 Register result = locs()->out(0).reg();
2019 if (IsPotentialUnboxedLoad()) { 2019 if (IsPotentialUnboxedLoad()) {
2020 Register temp = locs()->temp(1).reg(); 2020 Register temp = locs()->temp(1).reg();
2021 XmmRegister value = locs()->temp(0).fpu_reg(); 2021 XmmRegister value = locs()->temp(0).fpu_reg();
2022 2022
2023 Label load_pointer; 2023 Label load_pointer;
2024 Label load_double; 2024 Label load_double;
2025 Label load_float32x4; 2025 Label load_float32x4;
2026 Label load_float64x2; 2026 Label load_float64x2;
2027 2027
2028 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP); 2028 __ LoadObject(result, Field::ZoneHandle(field()->raw()), PP);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 __ Bind(&done); 2106 __ Bind(&done);
2107 } 2107 }
2108 2108
2109 2109
2110 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2110 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
2111 const intptr_t kNumInputs = 1; 2111 const intptr_t kNumInputs = 1;
2112 const intptr_t kNumTemps = 0; 2112 const intptr_t kNumTemps = 0;
2113 LocationSummary* locs = 2113 LocationSummary* locs =
2114 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2114 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2115 locs->set_in(0, Location::RegisterLocation(RAX)); 2115 locs->set_in(0, Location::RegisterLocation(RAX));
2116 locs->set_out(Location::RegisterLocation(RAX)); 2116 locs->set_out(0, Location::RegisterLocation(RAX));
2117 return locs; 2117 return locs;
2118 } 2118 }
2119 2119
2120 2120
2121 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2121 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2122 Register instantiator_reg = locs()->in(0).reg(); 2122 Register instantiator_reg = locs()->in(0).reg();
2123 Register result_reg = locs()->out().reg(); 2123 Register result_reg = locs()->out(0).reg();
2124 2124
2125 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2125 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2126 // A runtime call to instantiate the type is required. 2126 // A runtime call to instantiate the type is required.
2127 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. 2127 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
2128 __ PushObject(type(), PP); 2128 __ PushObject(type(), PP);
2129 __ pushq(instantiator_reg); // Push instantiator type arguments. 2129 __ pushq(instantiator_reg); // Push instantiator type arguments.
2130 compiler->GenerateRuntimeCall(token_pos(), 2130 compiler->GenerateRuntimeCall(token_pos(),
2131 deopt_id(), 2131 deopt_id(),
2132 kInstantiateTypeRuntimeEntry, 2132 kInstantiateTypeRuntimeEntry,
2133 2, 2133 2,
2134 locs()); 2134 locs());
2135 __ Drop(2); // Drop instantiator and uninstantiated type. 2135 __ Drop(2); // Drop instantiator and uninstantiated type.
2136 __ popq(result_reg); // Pop instantiated type. 2136 __ popq(result_reg); // Pop instantiated type.
2137 ASSERT(instantiator_reg == result_reg); 2137 ASSERT(instantiator_reg == result_reg);
2138 } 2138 }
2139 2139
2140 2140
2141 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( 2141 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2142 bool opt) const { 2142 bool opt) const {
2143 const intptr_t kNumInputs = 1; 2143 const intptr_t kNumInputs = 1;
2144 const intptr_t kNumTemps = 0; 2144 const intptr_t kNumTemps = 0;
2145 LocationSummary* locs = 2145 LocationSummary* locs =
2146 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2146 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2147 locs->set_in(0, Location::RegisterLocation(RAX)); 2147 locs->set_in(0, Location::RegisterLocation(RAX));
2148 locs->set_out(Location::RegisterLocation(RAX)); 2148 locs->set_out(0, Location::RegisterLocation(RAX));
2149 return locs; 2149 return locs;
2150 } 2150 }
2151 2151
2152 2152
2153 void InstantiateTypeArgumentsInstr::EmitNativeCode( 2153 void InstantiateTypeArgumentsInstr::EmitNativeCode(
2154 FlowGraphCompiler* compiler) { 2154 FlowGraphCompiler* compiler) {
2155 Register instantiator_reg = locs()->in(0).reg(); 2155 Register instantiator_reg = locs()->in(0).reg();
2156 Register result_reg = locs()->out().reg(); 2156 Register result_reg = locs()->out(0).reg();
2157 ASSERT(instantiator_reg == RAX); 2157 ASSERT(instantiator_reg == RAX);
2158 ASSERT(instantiator_reg == result_reg); 2158 ASSERT(instantiator_reg == result_reg);
2159 2159
2160 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2160 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2161 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2161 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2162 !type_arguments().CanShareInstantiatorTypeArguments( 2162 !type_arguments().CanShareInstantiatorTypeArguments(
2163 instantiator_class())); 2163 instantiator_class()));
2164 // If the instantiator is null and if the type argument vector 2164 // If the instantiator is null and if the type argument vector
2165 // instantiated from null becomes a vector of dynamic, then use null as 2165 // instantiated from null becomes a vector of dynamic, then use null as
2166 // the type arguments. 2166 // the type arguments.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 ASSERT(instantiator_reg == result_reg); 2209 ASSERT(instantiator_reg == result_reg);
2210 } 2210 }
2211 2211
2212 2212
2213 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { 2213 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
2214 const intptr_t kNumInputs = 0; 2214 const intptr_t kNumInputs = 0;
2215 const intptr_t kNumTemps = 1; 2215 const intptr_t kNumTemps = 1;
2216 LocationSummary* locs = 2216 LocationSummary* locs =
2217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2218 locs->set_temp(0, Location::RegisterLocation(R10)); 2218 locs->set_temp(0, Location::RegisterLocation(R10));
2219 locs->set_out(Location::RegisterLocation(RAX)); 2219 locs->set_out(0, Location::RegisterLocation(RAX));
2220 return locs; 2220 return locs;
2221 } 2221 }
2222 2222
2223 2223
2224 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2224 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2225 ASSERT(locs()->temp(0).reg() == R10); 2225 ASSERT(locs()->temp(0).reg() == R10);
2226 ASSERT(locs()->out().reg() == RAX); 2226 ASSERT(locs()->out(0).reg() == RAX);
2227 2227
2228 __ LoadImmediate(R10, Immediate(num_context_variables()), PP); 2228 __ LoadImmediate(R10, Immediate(num_context_variables()), PP);
2229 const ExternalLabel label("alloc_context", 2229 const ExternalLabel label("alloc_context",
2230 StubCode::AllocateContextEntryPoint()); 2230 StubCode::AllocateContextEntryPoint());
2231 compiler->GenerateCall(token_pos(), 2231 compiler->GenerateCall(token_pos(),
2232 &label, 2232 &label,
2233 PcDescriptors::kOther, 2233 PcDescriptors::kOther,
2234 locs()); 2234 locs());
2235 } 2235 }
2236 2236
2237 2237
2238 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { 2238 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const {
2239 const intptr_t kNumInputs = 1; 2239 const intptr_t kNumInputs = 1;
2240 const intptr_t kNumTemps = 0; 2240 const intptr_t kNumTemps = 0;
2241 LocationSummary* locs = 2241 LocationSummary* locs =
2242 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2242 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2243 locs->set_in(0, Location::RegisterLocation(RAX)); 2243 locs->set_in(0, Location::RegisterLocation(RAX));
2244 locs->set_out(Location::RegisterLocation(RAX)); 2244 locs->set_out(0, Location::RegisterLocation(RAX));
2245 return locs; 2245 return locs;
2246 } 2246 }
2247 2247
2248 2248
2249 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2249 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2250 Register context_value = locs()->in(0).reg(); 2250 Register context_value = locs()->in(0).reg();
2251 Register result = locs()->out().reg(); 2251 Register result = locs()->out(0).reg();
2252 2252
2253 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. 2253 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result.
2254 __ pushq(context_value); 2254 __ pushq(context_value);
2255 compiler->GenerateRuntimeCall(token_pos(), 2255 compiler->GenerateRuntimeCall(token_pos(),
2256 deopt_id(), 2256 deopt_id(),
2257 kCloneContextRuntimeEntry, 2257 kCloneContextRuntimeEntry,
2258 1, 2258 1,
2259 locs()); 2259 locs());
2260 __ popq(result); // Remove argument. 2260 __ popq(result); // Remove argument.
2261 __ popq(result); // Get result (cloned context). 2261 __ popq(result); // Get result (cloned context).
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 __ j(GREATER, overflow); 2384 __ j(GREATER, overflow);
2385 } 2385 }
2386 } 2386 }
2387 2387
2388 2388
2389 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2389 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2390 BinarySmiOpInstr* shift_left) { 2390 BinarySmiOpInstr* shift_left) {
2391 const bool is_truncating = shift_left->is_truncating(); 2391 const bool is_truncating = shift_left->is_truncating();
2392 const LocationSummary& locs = *shift_left->locs(); 2392 const LocationSummary& locs = *shift_left->locs();
2393 Register left = locs.in(0).reg(); 2393 Register left = locs.in(0).reg();
2394 Register result = locs.out().reg(); 2394 Register result = locs.out(0).reg();
2395 ASSERT(left == result); 2395 ASSERT(left == result);
2396 Label* deopt = shift_left->CanDeoptimize() ? 2396 Label* deopt = shift_left->CanDeoptimize() ?
2397 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; 2397 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL;
2398 if (locs.in(1).IsConstant()) { 2398 if (locs.in(1).IsConstant()) {
2399 const Object& constant = locs.in(1).constant(); 2399 const Object& constant = locs.in(1).constant();
2400 ASSERT(constant.IsSmi()); 2400 ASSERT(constant.IsSmi());
2401 // shlq operation masks the count to 6 bits. 2401 // shlq operation masks the count to 6 bits.
2402 const intptr_t kCountLimit = 0x3F; 2402 const intptr_t kCountLimit = 0x3F;
2403 const intptr_t value = Smi::Cast(constant).Value(); 2403 const intptr_t value = Smi::Cast(constant).Value();
2404 if (value == 0) { 2404 if (value == 0) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2530 (op_kind() != Token::kTRUNCDIV) && 2530 (op_kind() != Token::kTRUNCDIV) &&
2531 (op_kind() != Token::kSHL) && 2531 (op_kind() != Token::kSHL) &&
2532 (op_kind() != Token::kMUL) && 2532 (op_kind() != Token::kMUL) &&
2533 (op_kind() != Token::kMOD) && 2533 (op_kind() != Token::kMOD) &&
2534 CanBeImmediate(right_constant->value())) { 2534 CanBeImmediate(right_constant->value())) {
2535 const intptr_t kNumTemps = 0; 2535 const intptr_t kNumTemps = 0;
2536 LocationSummary* summary = 2536 LocationSummary* summary =
2537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2537 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2538 summary->set_in(0, Location::RequiresRegister()); 2538 summary->set_in(0, Location::RequiresRegister());
2539 summary->set_in(1, Location::Constant(right_constant->value())); 2539 summary->set_in(1, Location::Constant(right_constant->value()));
2540 summary->set_out(Location::SameAsFirstInput()); 2540 summary->set_out(0, Location::SameAsFirstInput());
2541 return summary; 2541 return summary;
2542 } 2542 }
2543 2543
2544 if (op_kind() == Token::kTRUNCDIV) { 2544 if (op_kind() == Token::kTRUNCDIV) {
2545 const intptr_t kNumTemps = 1; 2545 const intptr_t kNumTemps = 1;
2546 LocationSummary* summary = 2546 LocationSummary* summary =
2547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2548 if (RightIsPowerOfTwoConstant()) { 2548 if (RightIsPowerOfTwoConstant()) {
2549 summary->set_in(0, Location::RequiresRegister()); 2549 summary->set_in(0, Location::RequiresRegister());
2550 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2550 ConstantInstr* right_constant = right()->definition()->AsConstant();
2551 summary->set_in(1, Location::Constant(right_constant->value())); 2551 summary->set_in(1, Location::Constant(right_constant->value()));
2552 summary->set_temp(0, Location::RequiresRegister()); 2552 summary->set_temp(0, Location::RequiresRegister());
2553 summary->set_out(Location::SameAsFirstInput()); 2553 summary->set_out(0, Location::SameAsFirstInput());
2554 } else { 2554 } else {
2555 // Both inputs must be writable because they will be untagged. 2555 // Both inputs must be writable because they will be untagged.
2556 summary->set_in(0, Location::RegisterLocation(RAX)); 2556 summary->set_in(0, Location::RegisterLocation(RAX));
2557 summary->set_in(1, Location::WritableRegister()); 2557 summary->set_in(1, Location::WritableRegister());
2558 summary->set_out(Location::SameAsFirstInput()); 2558 summary->set_out(0, Location::SameAsFirstInput());
2559 // Will be used for sign extension and division. 2559 // Will be used for sign extension and division.
2560 summary->set_temp(0, Location::RegisterLocation(RDX)); 2560 summary->set_temp(0, Location::RegisterLocation(RDX));
2561 } 2561 }
2562 return summary; 2562 return summary;
2563 } else if (op_kind() == Token::kMOD) { 2563 } else if (op_kind() == Token::kMOD) {
2564 const intptr_t kNumTemps = 1; 2564 const intptr_t kNumTemps = 1;
2565 LocationSummary* summary = 2565 LocationSummary* summary =
2566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2567 // Both inputs must be writable because they will be untagged. 2567 // Both inputs must be writable because they will be untagged.
2568 summary->set_in(0, Location::RegisterLocation(RDX)); 2568 summary->set_in(0, Location::RegisterLocation(RDX));
2569 summary->set_in(1, Location::WritableRegister()); 2569 summary->set_in(1, Location::WritableRegister());
2570 summary->set_out(Location::SameAsFirstInput()); 2570 summary->set_out(0, Location::SameAsFirstInput());
2571 // Will be used for sign extension and division. 2571 // Will be used for sign extension and division.
2572 summary->set_temp(0, Location::RegisterLocation(RAX)); 2572 summary->set_temp(0, Location::RegisterLocation(RAX));
2573 return summary; 2573 return summary;
2574 } else if (op_kind() == Token::kSHR) { 2574 } else if (op_kind() == Token::kSHR) {
2575 const intptr_t kNumTemps = 0; 2575 const intptr_t kNumTemps = 0;
2576 LocationSummary* summary = 2576 LocationSummary* summary =
2577 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2577 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2578 summary->set_in(0, Location::RequiresRegister()); 2578 summary->set_in(0, Location::RequiresRegister());
2579 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); 2579 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
2580 summary->set_out(Location::SameAsFirstInput()); 2580 summary->set_out(0, Location::SameAsFirstInput());
2581 return summary; 2581 return summary;
2582 } else if (op_kind() == Token::kSHL) { 2582 } else if (op_kind() == Token::kSHL) {
2583 const intptr_t kNumTemps = 0; 2583 const intptr_t kNumTemps = 0;
2584 LocationSummary* summary = 2584 LocationSummary* summary =
2585 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2585 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2586 summary->set_in(0, Location::RequiresRegister()); 2586 summary->set_in(0, Location::RequiresRegister());
2587 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); 2587 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
2588 if (!is_truncating()) { 2588 if (!is_truncating()) {
2589 summary->AddTemp(Location::RequiresRegister()); 2589 summary->AddTemp(Location::RequiresRegister());
2590 } 2590 }
2591 summary->set_out(Location::SameAsFirstInput()); 2591 summary->set_out(0, Location::SameAsFirstInput());
2592 return summary; 2592 return summary;
2593 } else { 2593 } else {
2594 const intptr_t kNumTemps = 0; 2594 const intptr_t kNumTemps = 0;
2595 LocationSummary* summary = 2595 LocationSummary* summary =
2596 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2596 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2597 summary->set_in(0, Location::RequiresRegister()); 2597 summary->set_in(0, Location::RequiresRegister());
2598 ConstantInstr* constant = right()->definition()->AsConstant(); 2598 ConstantInstr* constant = right()->definition()->AsConstant();
2599 if (constant != NULL) { 2599 if (constant != NULL) {
2600 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2600 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2601 } else { 2601 } else {
2602 summary->set_in(1, Location::PrefersRegister()); 2602 summary->set_in(1, Location::PrefersRegister());
2603 } 2603 }
2604 summary->set_out(Location::SameAsFirstInput()); 2604 summary->set_out(0, Location::SameAsFirstInput());
2605 return summary; 2605 return summary;
2606 } 2606 }
2607 } 2607 }
2608 2608
2609 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2609 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2610 if (op_kind() == Token::kSHL) { 2610 if (op_kind() == Token::kSHL) {
2611 EmitSmiShiftLeft(compiler, this); 2611 EmitSmiShiftLeft(compiler, this);
2612 return; 2612 return;
2613 } 2613 }
2614 2614
2615 ASSERT(!is_truncating()); 2615 ASSERT(!is_truncating());
2616 Register left = locs()->in(0).reg(); 2616 Register left = locs()->in(0).reg();
2617 Register result = locs()->out().reg(); 2617 Register result = locs()->out(0).reg();
2618 ASSERT(left == result); 2618 ASSERT(left == result);
2619 Label* deopt = NULL; 2619 Label* deopt = NULL;
2620 if (CanDeoptimize()) { 2620 if (CanDeoptimize()) {
2621 deopt = compiler->AddDeoptStub(deopt_id(), 2621 deopt = compiler->AddDeoptStub(deopt_id(),
2622 kDeoptBinarySmiOp); 2622 kDeoptBinarySmiOp);
2623 } 2623 }
2624 2624
2625 if (locs()->in(1).IsConstant()) { 2625 if (locs()->in(1).IsConstant()) {
2626 const Object& constant = locs()->in(1).constant(); 2626 const Object& constant = locs()->in(1).constant();
2627 ASSERT(constant.IsSmi()); 2627 ASSERT(constant.IsSmi());
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
3010 3010
3011 3011
3012 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 3012 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
3013 const intptr_t kNumInputs = 1; 3013 const intptr_t kNumInputs = 1;
3014 const intptr_t kNumTemps = 0; 3014 const intptr_t kNumTemps = 0;
3015 LocationSummary* summary = 3015 LocationSummary* summary =
3016 new LocationSummary(kNumInputs, 3016 new LocationSummary(kNumInputs,
3017 kNumTemps, 3017 kNumTemps,
3018 LocationSummary::kCallOnSlowPath); 3018 LocationSummary::kCallOnSlowPath);
3019 summary->set_in(0, Location::RequiresFpuRegister()); 3019 summary->set_in(0, Location::RequiresFpuRegister());
3020 summary->set_out(Location::RequiresRegister()); 3020 summary->set_out(0, Location::RequiresRegister());
3021 return summary; 3021 return summary;
3022 } 3022 }
3023 3023
3024 3024
3025 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3025 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3026 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 3026 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
3027 compiler->AddSlowPathCode(slow_path); 3027 compiler->AddSlowPathCode(slow_path);
3028 3028
3029 Register out_reg = locs()->out().reg(); 3029 Register out_reg = locs()->out(0).reg();
3030 XmmRegister value = locs()->in(0).fpu_reg(); 3030 XmmRegister value = locs()->in(0).fpu_reg();
3031 3031
3032 __ TryAllocate(compiler->double_class(), 3032 __ TryAllocate(compiler->double_class(),
3033 slow_path->entry_label(), 3033 slow_path->entry_label(),
3034 Assembler::kFarJump, 3034 Assembler::kFarJump,
3035 out_reg, 3035 out_reg,
3036 PP); 3036 PP);
3037 __ Bind(slow_path->exit_label()); 3037 __ Bind(slow_path->exit_label());
3038 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 3038 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
3039 } 3039 }
3040 3040
3041 3041
3042 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { 3042 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
3043 const intptr_t kNumInputs = 1; 3043 const intptr_t kNumInputs = 1;
3044 const intptr_t kNumTemps = 0; 3044 const intptr_t kNumTemps = 0;
3045 LocationSummary* summary = 3045 LocationSummary* summary =
3046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3047 const bool needs_writable_input = (value()->Type()->ToCid() != kDoubleCid); 3047 const bool needs_writable_input = (value()->Type()->ToCid() != kDoubleCid);
3048 summary->set_in(0, needs_writable_input 3048 summary->set_in(0, needs_writable_input
3049 ? Location::WritableRegister() 3049 ? Location::WritableRegister()
3050 : Location::RequiresRegister()); 3050 : Location::RequiresRegister());
3051 summary->set_out(Location::RequiresFpuRegister()); 3051 summary->set_out(0, Location::RequiresFpuRegister());
3052 return summary; 3052 return summary;
3053 } 3053 }
3054 3054
3055 3055
3056 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3056 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3057 const intptr_t value_cid = value()->Type()->ToCid(); 3057 const intptr_t value_cid = value()->Type()->ToCid();
3058 const Register value = locs()->in(0).reg(); 3058 const Register value = locs()->in(0).reg();
3059 const XmmRegister result = locs()->out().fpu_reg(); 3059 const XmmRegister result = locs()->out(0).fpu_reg();
3060 3060
3061 if (value_cid == kDoubleCid) { 3061 if (value_cid == kDoubleCid) {
3062 __ movsd(result, FieldAddress(value, Double::value_offset())); 3062 __ movsd(result, FieldAddress(value, Double::value_offset()));
3063 } else if (value_cid == kSmiCid) { 3063 } else if (value_cid == kSmiCid) {
3064 __ SmiUntag(value); // Untag input before conversion. 3064 __ SmiUntag(value); // Untag input before conversion.
3065 __ cvtsi2sd(result, value); 3065 __ cvtsi2sd(result, value);
3066 } else { 3066 } else {
3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
3068 Label is_smi, done; 3068 Label is_smi, done;
3069 __ testq(value, Immediate(kSmiTagMask)); 3069 __ testq(value, Immediate(kSmiTagMask));
(...skipping 11 matching lines...) Expand all
3081 3081
3082 3082
3083 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { 3083 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3084 const intptr_t kNumInputs = 1; 3084 const intptr_t kNumInputs = 1;
3085 const intptr_t kNumTemps = 0; 3085 const intptr_t kNumTemps = 0;
3086 LocationSummary* summary = 3086 LocationSummary* summary =
3087 new LocationSummary(kNumInputs, 3087 new LocationSummary(kNumInputs,
3088 kNumTemps, 3088 kNumTemps,
3089 LocationSummary::kCallOnSlowPath); 3089 LocationSummary::kCallOnSlowPath);
3090 summary->set_in(0, Location::RequiresFpuRegister()); 3090 summary->set_in(0, Location::RequiresFpuRegister());
3091 summary->set_out(Location::RequiresRegister()); 3091 summary->set_out(0, Location::RequiresRegister());
3092 return summary; 3092 return summary;
3093 } 3093 }
3094 3094
3095 3095
3096 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3096 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3097 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); 3097 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
3098 compiler->AddSlowPathCode(slow_path); 3098 compiler->AddSlowPathCode(slow_path);
3099 3099
3100 Register out_reg = locs()->out().reg(); 3100 Register out_reg = locs()->out(0).reg();
3101 XmmRegister value = locs()->in(0).fpu_reg(); 3101 XmmRegister value = locs()->in(0).fpu_reg();
3102 3102
3103 __ TryAllocate(compiler->float32x4_class(), 3103 __ TryAllocate(compiler->float32x4_class(),
3104 slow_path->entry_label(), 3104 slow_path->entry_label(),
3105 Assembler::kFarJump, 3105 Assembler::kFarJump,
3106 out_reg, 3106 out_reg,
3107 PP); 3107 PP);
3108 __ Bind(slow_path->exit_label()); 3108 __ Bind(slow_path->exit_label());
3109 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value); 3109 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
3110 } 3110 }
3111 3111
3112 3112
3113 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { 3113 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3114 const intptr_t kNumInputs = 1; 3114 const intptr_t kNumInputs = 1;
3115 return LocationSummary::Make(kNumInputs, 3115 return LocationSummary::Make(kNumInputs,
3116 Location::RequiresFpuRegister(), 3116 Location::RequiresFpuRegister(),
3117 LocationSummary::kNoCall); 3117 LocationSummary::kNoCall);
3118 } 3118 }
3119 3119
3120 3120
3121 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3121 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3122 const intptr_t value_cid = value()->Type()->ToCid(); 3122 const intptr_t value_cid = value()->Type()->ToCid();
3123 const Register value = locs()->in(0).reg(); 3123 const Register value = locs()->in(0).reg();
3124 const XmmRegister result = locs()->out().fpu_reg(); 3124 const XmmRegister result = locs()->out(0).fpu_reg();
3125 3125
3126 if (value_cid != kFloat32x4Cid) { 3126 if (value_cid != kFloat32x4Cid) {
3127 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3127 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3128 __ testq(value, Immediate(kSmiTagMask)); 3128 __ testq(value, Immediate(kSmiTagMask));
3129 __ j(ZERO, deopt); 3129 __ j(ZERO, deopt);
3130 __ CompareClassId(value, kFloat32x4Cid); 3130 __ CompareClassId(value, kFloat32x4Cid);
3131 __ j(NOT_EQUAL, deopt); 3131 __ j(NOT_EQUAL, deopt);
3132 } 3132 }
3133 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3133 __ movups(result, FieldAddress(value, Float32x4::value_offset()));
3134 } 3134 }
3135 3135
3136 3136
3137 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3137 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3138 const intptr_t kNumInputs = 1; 3138 const intptr_t kNumInputs = 1;
3139 const intptr_t kNumTemps = 0; 3139 const intptr_t kNumTemps = 0;
3140 LocationSummary* summary = 3140 LocationSummary* summary =
3141 new LocationSummary(kNumInputs, 3141 new LocationSummary(kNumInputs,
3142 kNumTemps, 3142 kNumTemps,
3143 LocationSummary::kCallOnSlowPath); 3143 LocationSummary::kCallOnSlowPath);
3144 summary->set_in(0, Location::RequiresFpuRegister()); 3144 summary->set_in(0, Location::RequiresFpuRegister());
3145 summary->set_out(Location::RequiresRegister()); 3145 summary->set_out(0, Location::RequiresRegister());
3146 return summary; 3146 return summary;
3147 } 3147 }
3148 3148
3149 3149
3150 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3150 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3151 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); 3151 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
3152 compiler->AddSlowPathCode(slow_path); 3152 compiler->AddSlowPathCode(slow_path);
3153 3153
3154 Register out_reg = locs()->out().reg(); 3154 Register out_reg = locs()->out(0).reg();
3155 XmmRegister value = locs()->in(0).fpu_reg(); 3155 XmmRegister value = locs()->in(0).fpu_reg();
3156 3156
3157 __ TryAllocate(compiler->float64x2_class(), 3157 __ TryAllocate(compiler->float64x2_class(),
3158 slow_path->entry_label(), 3158 slow_path->entry_label(),
3159 Assembler::kFarJump, 3159 Assembler::kFarJump,
3160 out_reg, 3160 out_reg,
3161 kNoRegister); 3161 kNoRegister);
3162 __ Bind(slow_path->exit_label()); 3162 __ Bind(slow_path->exit_label());
3163 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); 3163 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
3164 } 3164 }
3165 3165
3166 3166
3167 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3167 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3168 const intptr_t value_cid = value()->Type()->ToCid(); 3168 const intptr_t value_cid = value()->Type()->ToCid();
3169 const intptr_t kNumInputs = 1; 3169 const intptr_t kNumInputs = 1;
3170 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; 3170 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
3171 LocationSummary* summary = 3171 LocationSummary* summary =
3172 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3172 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3173 summary->set_in(0, Location::RequiresRegister()); 3173 summary->set_in(0, Location::RequiresRegister());
3174 summary->set_out(Location::RequiresFpuRegister()); 3174 summary->set_out(0, Location::RequiresFpuRegister());
3175 return summary; 3175 return summary;
3176 } 3176 }
3177 3177
3178 3178
3179 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3179 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3180 const intptr_t value_cid = value()->Type()->ToCid(); 3180 const intptr_t value_cid = value()->Type()->ToCid();
3181 const Register value = locs()->in(0).reg(); 3181 const Register value = locs()->in(0).reg();
3182 const XmmRegister result = locs()->out().fpu_reg(); 3182 const XmmRegister result = locs()->out(0).fpu_reg();
3183 3183
3184 if (value_cid != kFloat64x2Cid) { 3184 if (value_cid != kFloat64x2Cid) {
3185 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3185 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3186 __ testq(value, Immediate(kSmiTagMask)); 3186 __ testq(value, Immediate(kSmiTagMask));
3187 __ j(ZERO, deopt); 3187 __ j(ZERO, deopt);
3188 __ CompareClassId(value, kFloat64x2Cid); 3188 __ CompareClassId(value, kFloat64x2Cid);
3189 __ j(NOT_EQUAL, deopt); 3189 __ j(NOT_EQUAL, deopt);
3190 } 3190 }
3191 __ movups(result, FieldAddress(value, Float64x2::value_offset())); 3191 __ movups(result, FieldAddress(value, Float64x2::value_offset()));
3192 } 3192 }
3193 3193
3194 3194
3195 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3195 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
3196 const intptr_t kNumInputs = 1; 3196 const intptr_t kNumInputs = 1;
3197 const intptr_t kNumTemps = 0; 3197 const intptr_t kNumTemps = 0;
3198 LocationSummary* summary = 3198 LocationSummary* summary =
3199 new LocationSummary(kNumInputs, 3199 new LocationSummary(kNumInputs,
3200 kNumTemps, 3200 kNumTemps,
3201 LocationSummary::kCallOnSlowPath); 3201 LocationSummary::kCallOnSlowPath);
3202 summary->set_in(0, Location::RequiresFpuRegister()); 3202 summary->set_in(0, Location::RequiresFpuRegister());
3203 summary->set_out(Location::RequiresRegister()); 3203 summary->set_out(0, Location::RequiresRegister());
3204 return summary; 3204 return summary;
3205 } 3205 }
3206 3206
3207 3207
3208 class BoxInt32x4SlowPath : public SlowPathCode { 3208 class BoxInt32x4SlowPath : public SlowPathCode {
3209 public: 3209 public:
3210 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) 3210 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction)
3211 : instruction_(instruction) { } 3211 : instruction_(instruction) { }
3212 3212
3213 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 3213 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
3214 __ Comment("BoxInt32x4SlowPath"); 3214 __ Comment("BoxInt32x4SlowPath");
3215 __ Bind(entry_label()); 3215 __ Bind(entry_label());
3216 const Class& int32x4_class = compiler->int32x4_class(); 3216 const Class& int32x4_class = compiler->int32x4_class();
3217 const Code& stub = 3217 const Code& stub =
3218 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); 3218 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class));
3219 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); 3219 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint());
3220 3220
3221 LocationSummary* locs = instruction_->locs(); 3221 LocationSummary* locs = instruction_->locs();
3222 locs->live_registers()->Remove(locs->out()); 3222 locs->live_registers()->Remove(locs->out(0));
3223 3223
3224 compiler->SaveLiveRegisters(locs); 3224 compiler->SaveLiveRegisters(locs);
3225 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 3225 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
3226 &label, 3226 &label,
3227 PcDescriptors::kOther, 3227 PcDescriptors::kOther,
3228 locs); 3228 locs);
3229 __ MoveRegister(locs->out().reg(), RAX); 3229 __ MoveRegister(locs->out(0).reg(), RAX);
3230 compiler->RestoreLiveRegisters(locs); 3230 compiler->RestoreLiveRegisters(locs);
3231 3231
3232 __ jmp(exit_label()); 3232 __ jmp(exit_label());
3233 } 3233 }
3234 3234
3235 private: 3235 private:
3236 BoxInt32x4Instr* instruction_; 3236 BoxInt32x4Instr* instruction_;
3237 }; 3237 };
3238 3238
3239 3239
3240 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3240 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3241 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); 3241 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this);
3242 compiler->AddSlowPathCode(slow_path); 3242 compiler->AddSlowPathCode(slow_path);
3243 3243
3244 Register out_reg = locs()->out().reg(); 3244 Register out_reg = locs()->out(0).reg();
3245 XmmRegister value = locs()->in(0).fpu_reg(); 3245 XmmRegister value = locs()->in(0).fpu_reg();
3246 3246
3247 __ TryAllocate(compiler->int32x4_class(), 3247 __ TryAllocate(compiler->int32x4_class(),
3248 slow_path->entry_label(), 3248 slow_path->entry_label(),
3249 Assembler::kFarJump, 3249 Assembler::kFarJump,
3250 out_reg, 3250 out_reg,
3251 PP); 3251 PP);
3252 __ Bind(slow_path->exit_label()); 3252 __ Bind(slow_path->exit_label());
3253 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value); 3253 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
3254 } 3254 }
3255 3255
3256 3256
3257 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { 3257 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const {
3258 const intptr_t kNumInputs = 1; 3258 const intptr_t kNumInputs = 1;
3259 const intptr_t kNumTemps = 0; 3259 const intptr_t kNumTemps = 0;
3260 LocationSummary* summary = 3260 LocationSummary* summary =
3261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3262 summary->set_in(0, Location::RequiresRegister()); 3262 summary->set_in(0, Location::RequiresRegister());
3263 summary->set_out(Location::RequiresFpuRegister()); 3263 summary->set_out(0, Location::RequiresFpuRegister());
3264 return summary; 3264 return summary;
3265 } 3265 }
3266 3266
3267 3267
3268 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3268 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3269 const intptr_t value_cid = value()->Type()->ToCid(); 3269 const intptr_t value_cid = value()->Type()->ToCid();
3270 const Register value = locs()->in(0).reg(); 3270 const Register value = locs()->in(0).reg();
3271 const XmmRegister result = locs()->out().fpu_reg(); 3271 const XmmRegister result = locs()->out(0).fpu_reg();
3272 3272
3273 if (value_cid != kInt32x4Cid) { 3273 if (value_cid != kInt32x4Cid) {
3274 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3274 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3275 __ testq(value, Immediate(kSmiTagMask)); 3275 __ testq(value, Immediate(kSmiTagMask));
3276 __ j(ZERO, deopt); 3276 __ j(ZERO, deopt);
3277 __ CompareClassId(value, kInt32x4Cid); 3277 __ CompareClassId(value, kInt32x4Cid);
3278 __ j(NOT_EQUAL, deopt); 3278 __ j(NOT_EQUAL, deopt);
3279 } 3279 }
3280 __ movups(result, FieldAddress(value, Int32x4::value_offset())); 3280 __ movups(result, FieldAddress(value, Int32x4::value_offset()));
3281 } 3281 }
3282 3282
3283 3283
3284 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 3284 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3285 const intptr_t kNumInputs = 2; 3285 const intptr_t kNumInputs = 2;
3286 const intptr_t kNumTemps = 0; 3286 const intptr_t kNumTemps = 0;
3287 LocationSummary* summary = 3287 LocationSummary* summary =
3288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3289 summary->set_in(0, Location::RequiresFpuRegister()); 3289 summary->set_in(0, Location::RequiresFpuRegister());
3290 summary->set_in(1, Location::RequiresFpuRegister()); 3290 summary->set_in(1, Location::RequiresFpuRegister());
3291 summary->set_out(Location::SameAsFirstInput()); 3291 summary->set_out(0, Location::SameAsFirstInput());
3292 return summary; 3292 return summary;
3293 } 3293 }
3294 3294
3295 3295
3296 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3296 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3297 XmmRegister left = locs()->in(0).fpu_reg(); 3297 XmmRegister left = locs()->in(0).fpu_reg();
3298 XmmRegister right = locs()->in(1).fpu_reg(); 3298 XmmRegister right = locs()->in(1).fpu_reg();
3299 3299
3300 ASSERT(locs()->out().fpu_reg() == left); 3300 ASSERT(locs()->out(0).fpu_reg() == left);
3301 3301
3302 switch (op_kind()) { 3302 switch (op_kind()) {
3303 case Token::kADD: __ addsd(left, right); break; 3303 case Token::kADD: __ addsd(left, right); break;
3304 case Token::kSUB: __ subsd(left, right); break; 3304 case Token::kSUB: __ subsd(left, right); break;
3305 case Token::kMUL: __ mulsd(left, right); break; 3305 case Token::kMUL: __ mulsd(left, right); break;
3306 case Token::kDIV: __ divsd(left, right); break; 3306 case Token::kDIV: __ divsd(left, right); break;
3307 default: UNREACHABLE(); 3307 default: UNREACHABLE();
3308 } 3308 }
3309 } 3309 }
3310 3310
3311 3311
3312 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { 3312 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const {
3313 const intptr_t kNumInputs = 2; 3313 const intptr_t kNumInputs = 2;
3314 const intptr_t kNumTemps = 0; 3314 const intptr_t kNumTemps = 0;
3315 LocationSummary* summary = 3315 LocationSummary* summary =
3316 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3316 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3317 summary->set_in(0, Location::RequiresFpuRegister()); 3317 summary->set_in(0, Location::RequiresFpuRegister());
3318 summary->set_in(1, Location::RequiresFpuRegister()); 3318 summary->set_in(1, Location::RequiresFpuRegister());
3319 summary->set_out(Location::SameAsFirstInput()); 3319 summary->set_out(0, Location::SameAsFirstInput());
3320 return summary; 3320 return summary;
3321 } 3321 }
3322 3322
3323 3323
3324 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3324 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3325 XmmRegister left = locs()->in(0).fpu_reg(); 3325 XmmRegister left = locs()->in(0).fpu_reg();
3326 XmmRegister right = locs()->in(1).fpu_reg(); 3326 XmmRegister right = locs()->in(1).fpu_reg();
3327 3327
3328 ASSERT(locs()->out().fpu_reg() == left); 3328 ASSERT(locs()->out(0).fpu_reg() == left);
3329 3329
3330 switch (op_kind()) { 3330 switch (op_kind()) {
3331 case Token::kADD: __ addps(left, right); break; 3331 case Token::kADD: __ addps(left, right); break;
3332 case Token::kSUB: __ subps(left, right); break; 3332 case Token::kSUB: __ subps(left, right); break;
3333 case Token::kMUL: __ mulps(left, right); break; 3333 case Token::kMUL: __ mulps(left, right); break;
3334 case Token::kDIV: __ divps(left, right); break; 3334 case Token::kDIV: __ divps(left, right); break;
3335 default: UNREACHABLE(); 3335 default: UNREACHABLE();
3336 } 3336 }
3337 } 3337 }
3338 3338
3339 3339
3340 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { 3340 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const {
3341 const intptr_t kNumInputs = 2; 3341 const intptr_t kNumInputs = 2;
3342 const intptr_t kNumTemps = 0; 3342 const intptr_t kNumTemps = 0;
3343 LocationSummary* summary = 3343 LocationSummary* summary =
3344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3345 summary->set_in(0, Location::RequiresFpuRegister()); 3345 summary->set_in(0, Location::RequiresFpuRegister());
3346 summary->set_in(1, Location::RequiresFpuRegister()); 3346 summary->set_in(1, Location::RequiresFpuRegister());
3347 summary->set_out(Location::SameAsFirstInput()); 3347 summary->set_out(0, Location::SameAsFirstInput());
3348 return summary; 3348 return summary;
3349 } 3349 }
3350 3350
3351 3351
3352 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3352 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3353 XmmRegister left = locs()->in(0).fpu_reg(); 3353 XmmRegister left = locs()->in(0).fpu_reg();
3354 XmmRegister right = locs()->in(1).fpu_reg(); 3354 XmmRegister right = locs()->in(1).fpu_reg();
3355 3355
3356 ASSERT(locs()->out().fpu_reg() == left); 3356 ASSERT(locs()->out(0).fpu_reg() == left);
3357 3357
3358 switch (op_kind()) { 3358 switch (op_kind()) {
3359 case Token::kADD: __ addpd(left, right); break; 3359 case Token::kADD: __ addpd(left, right); break;
3360 case Token::kSUB: __ subpd(left, right); break; 3360 case Token::kSUB: __ subpd(left, right); break;
3361 case Token::kMUL: __ mulpd(left, right); break; 3361 case Token::kMUL: __ mulpd(left, right); break;
3362 case Token::kDIV: __ divpd(left, right); break; 3362 case Token::kDIV: __ divpd(left, right); break;
3363 default: UNREACHABLE(); 3363 default: UNREACHABLE();
3364 } 3364 }
3365 } 3365 }
3366 3366
3367 3367
3368 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { 3368 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const {
3369 const intptr_t kNumInputs = 1; 3369 const intptr_t kNumInputs = 1;
3370 const intptr_t kNumTemps = 0; 3370 const intptr_t kNumTemps = 0;
3371 LocationSummary* summary = 3371 LocationSummary* summary =
3372 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3372 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3373 summary->set_in(0, Location::RequiresFpuRegister()); 3373 summary->set_in(0, Location::RequiresFpuRegister());
3374 summary->set_out(Location::SameAsFirstInput()); 3374 summary->set_out(0, Location::SameAsFirstInput());
3375 return summary; 3375 return summary;
3376 } 3376 }
3377 3377
3378 3378
3379 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3379 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3380 XmmRegister value = locs()->in(0).fpu_reg(); 3380 XmmRegister value = locs()->in(0).fpu_reg();
3381 3381
3382 ASSERT(locs()->out().fpu_reg() == value); 3382 ASSERT(locs()->out(0).fpu_reg() == value);
3383 3383
3384 switch (op_kind()) { 3384 switch (op_kind()) {
3385 case MethodRecognizer::kFloat32x4ShuffleX: 3385 case MethodRecognizer::kFloat32x4ShuffleX:
3386 // Shuffle not necessary. 3386 // Shuffle not necessary.
3387 __ cvtss2sd(value, value); 3387 __ cvtss2sd(value, value);
3388 break; 3388 break;
3389 case MethodRecognizer::kFloat32x4ShuffleY: 3389 case MethodRecognizer::kFloat32x4ShuffleY:
3390 __ shufps(value, value, Immediate(0x55)); 3390 __ shufps(value, value, Immediate(0x55));
3391 __ cvtss2sd(value, value); 3391 __ cvtss2sd(value, value);
3392 break; 3392 break;
(...skipping 14 matching lines...) Expand all
3407 } 3407 }
3408 3408
3409 3409
3410 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { 3410 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const {
3411 const intptr_t kNumInputs = 2; 3411 const intptr_t kNumInputs = 2;
3412 const intptr_t kNumTemps = 0; 3412 const intptr_t kNumTemps = 0;
3413 LocationSummary* summary = 3413 LocationSummary* summary =
3414 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3414 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3415 summary->set_in(0, Location::RequiresFpuRegister()); 3415 summary->set_in(0, Location::RequiresFpuRegister());
3416 summary->set_in(1, Location::RequiresFpuRegister()); 3416 summary->set_in(1, Location::RequiresFpuRegister());
3417 summary->set_out(Location::SameAsFirstInput()); 3417 summary->set_out(0, Location::SameAsFirstInput());
3418 return summary; 3418 return summary;
3419 } 3419 }
3420 3420
3421 3421
3422 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3422 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3423 XmmRegister left = locs()->in(0).fpu_reg(); 3423 XmmRegister left = locs()->in(0).fpu_reg();
3424 XmmRegister right = locs()->in(1).fpu_reg(); 3424 XmmRegister right = locs()->in(1).fpu_reg();
3425 3425
3426 ASSERT(locs()->out().fpu_reg() == left); 3426 ASSERT(locs()->out(0).fpu_reg() == left);
3427 switch (op_kind()) { 3427 switch (op_kind()) {
3428 case MethodRecognizer::kFloat32x4ShuffleMix: 3428 case MethodRecognizer::kFloat32x4ShuffleMix:
3429 case MethodRecognizer::kInt32x4ShuffleMix: 3429 case MethodRecognizer::kInt32x4ShuffleMix:
3430 __ shufps(left, right, Immediate(mask_)); 3430 __ shufps(left, right, Immediate(mask_));
3431 break; 3431 break;
3432 default: UNREACHABLE(); 3432 default: UNREACHABLE();
3433 } 3433 }
3434 } 3434 }
3435 3435
3436 3436
3437 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { 3437 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const {
3438 const intptr_t kNumInputs = 1; 3438 const intptr_t kNumInputs = 1;
3439 const intptr_t kNumTemps = 0; 3439 const intptr_t kNumTemps = 0;
3440 LocationSummary* summary = 3440 LocationSummary* summary =
3441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3442 summary->set_in(0, Location::RequiresFpuRegister()); 3442 summary->set_in(0, Location::RequiresFpuRegister());
3443 summary->set_out(Location::RequiresRegister()); 3443 summary->set_out(0, Location::RequiresRegister());
3444 return summary; 3444 return summary;
3445 } 3445 }
3446 3446
3447 3447
3448 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3448 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3449 XmmRegister value = locs()->in(0).fpu_reg(); 3449 XmmRegister value = locs()->in(0).fpu_reg();
3450 Register out = locs()->out().reg(); 3450 Register out = locs()->out(0).reg();
3451 3451
3452 __ movmskps(out, value); 3452 __ movmskps(out, value);
3453 __ SmiTag(out); 3453 __ SmiTag(out);
3454 } 3454 }
3455 3455
3456 3456
3457 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( 3457 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary(
3458 bool opt) const { 3458 bool opt) const {
3459 const intptr_t kNumInputs = 4; 3459 const intptr_t kNumInputs = 4;
3460 const intptr_t kNumTemps = 0; 3460 const intptr_t kNumTemps = 0;
3461 LocationSummary* summary = 3461 LocationSummary* summary =
3462 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3462 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3463 summary->set_in(0, Location::RequiresFpuRegister()); 3463 summary->set_in(0, Location::RequiresFpuRegister());
3464 summary->set_in(1, Location::RequiresFpuRegister()); 3464 summary->set_in(1, Location::RequiresFpuRegister());
3465 summary->set_in(2, Location::RequiresFpuRegister()); 3465 summary->set_in(2, Location::RequiresFpuRegister());
3466 summary->set_in(3, Location::RequiresFpuRegister()); 3466 summary->set_in(3, Location::RequiresFpuRegister());
3467 summary->set_out(Location::SameAsFirstInput()); 3467 summary->set_out(0, Location::SameAsFirstInput());
3468 return summary; 3468 return summary;
3469 } 3469 }
3470 3470
3471 3471
3472 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3472 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3473 XmmRegister v0 = locs()->in(0).fpu_reg(); 3473 XmmRegister v0 = locs()->in(0).fpu_reg();
3474 XmmRegister v1 = locs()->in(1).fpu_reg(); 3474 XmmRegister v1 = locs()->in(1).fpu_reg();
3475 XmmRegister v2 = locs()->in(2).fpu_reg(); 3475 XmmRegister v2 = locs()->in(2).fpu_reg();
3476 XmmRegister v3 = locs()->in(3).fpu_reg(); 3476 XmmRegister v3 = locs()->in(3).fpu_reg();
3477 ASSERT(v0 == locs()->out().fpu_reg()); 3477 ASSERT(v0 == locs()->out(0).fpu_reg());
3478 __ AddImmediate(RSP, Immediate(-16), PP); 3478 __ AddImmediate(RSP, Immediate(-16), PP);
3479 __ cvtsd2ss(v0, v0); 3479 __ cvtsd2ss(v0, v0);
3480 __ movss(Address(RSP, 0), v0); 3480 __ movss(Address(RSP, 0), v0);
3481 __ movsd(v0, v1); 3481 __ movsd(v0, v1);
3482 __ cvtsd2ss(v0, v0); 3482 __ cvtsd2ss(v0, v0);
3483 __ movss(Address(RSP, 4), v0); 3483 __ movss(Address(RSP, 4), v0);
3484 __ movsd(v0, v2); 3484 __ movsd(v0, v2);
3485 __ cvtsd2ss(v0, v0); 3485 __ cvtsd2ss(v0, v0);
3486 __ movss(Address(RSP, 8), v0); 3486 __ movss(Address(RSP, 8), v0);
3487 __ movsd(v0, v3); 3487 __ movsd(v0, v3);
3488 __ cvtsd2ss(v0, v0); 3488 __ cvtsd2ss(v0, v0);
3489 __ movss(Address(RSP, 12), v0); 3489 __ movss(Address(RSP, 12), v0);
3490 __ movups(v0, Address(RSP, 0)); 3490 __ movups(v0, Address(RSP, 0));
3491 __ AddImmediate(RSP, Immediate(16), PP); 3491 __ AddImmediate(RSP, Immediate(16), PP);
3492 } 3492 }
3493 3493
3494 3494
3495 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { 3495 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const {
3496 const intptr_t kNumInputs = 0; 3496 const intptr_t kNumInputs = 0;
3497 const intptr_t kNumTemps = 0; 3497 const intptr_t kNumTemps = 0;
3498 LocationSummary* summary = 3498 LocationSummary* summary =
3499 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3499 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3500 summary->set_out(Location::RequiresFpuRegister()); 3500 summary->set_out(0, Location::RequiresFpuRegister());
3501 return summary; 3501 return summary;
3502 } 3502 }
3503 3503
3504 3504
3505 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3505 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3506 XmmRegister value = locs()->out().fpu_reg(); 3506 XmmRegister value = locs()->out(0).fpu_reg();
3507 __ xorps(value, value); 3507 __ xorps(value, value);
3508 } 3508 }
3509 3509
3510 3510
3511 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { 3511 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const {
3512 const intptr_t kNumInputs = 1; 3512 const intptr_t kNumInputs = 1;
3513 const intptr_t kNumTemps = 0; 3513 const intptr_t kNumTemps = 0;
3514 LocationSummary* summary = 3514 LocationSummary* summary =
3515 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3515 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3516 summary->set_in(0, Location::RequiresFpuRegister()); 3516 summary->set_in(0, Location::RequiresFpuRegister());
3517 summary->set_out(Location::SameAsFirstInput()); 3517 summary->set_out(0, Location::SameAsFirstInput());
3518 return summary; 3518 return summary;
3519 } 3519 }
3520 3520
3521 3521
3522 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3522 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3523 XmmRegister value = locs()->out().fpu_reg(); 3523 XmmRegister value = locs()->out(0).fpu_reg();
3524 ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg()); 3524 ASSERT(locs()->in(0).fpu_reg() == locs()->out(0).fpu_reg());
3525 // Convert to Float32. 3525 // Convert to Float32.
3526 __ cvtsd2ss(value, value); 3526 __ cvtsd2ss(value, value);
3527 // Splat across all lanes. 3527 // Splat across all lanes.
3528 __ shufps(value, value, Immediate(0x00)); 3528 __ shufps(value, value, Immediate(0x00));
3529 } 3529 }
3530 3530
3531 3531
3532 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { 3532 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const {
3533 const intptr_t kNumInputs = 2; 3533 const intptr_t kNumInputs = 2;
3534 const intptr_t kNumTemps = 0; 3534 const intptr_t kNumTemps = 0;
3535 LocationSummary* summary = 3535 LocationSummary* summary =
3536 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3536 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3537 summary->set_in(0, Location::RequiresFpuRegister()); 3537 summary->set_in(0, Location::RequiresFpuRegister());
3538 summary->set_in(1, Location::RequiresFpuRegister()); 3538 summary->set_in(1, Location::RequiresFpuRegister());
3539 summary->set_out(Location::SameAsFirstInput()); 3539 summary->set_out(0, Location::SameAsFirstInput());
3540 return summary; 3540 return summary;
3541 } 3541 }
3542 3542
3543 3543
3544 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3544 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3545 XmmRegister left = locs()->in(0).fpu_reg(); 3545 XmmRegister left = locs()->in(0).fpu_reg();
3546 XmmRegister right = locs()->in(1).fpu_reg(); 3546 XmmRegister right = locs()->in(1).fpu_reg();
3547 3547
3548 ASSERT(locs()->out().fpu_reg() == left); 3548 ASSERT(locs()->out(0).fpu_reg() == left);
3549 3549
3550 switch (op_kind()) { 3550 switch (op_kind()) {
3551 case MethodRecognizer::kFloat32x4Equal: 3551 case MethodRecognizer::kFloat32x4Equal:
3552 __ cmppseq(left, right); 3552 __ cmppseq(left, right);
3553 break; 3553 break;
3554 case MethodRecognizer::kFloat32x4NotEqual: 3554 case MethodRecognizer::kFloat32x4NotEqual:
3555 __ cmppsneq(left, right); 3555 __ cmppsneq(left, right);
3556 break; 3556 break;
3557 case MethodRecognizer::kFloat32x4GreaterThan: 3557 case MethodRecognizer::kFloat32x4GreaterThan:
3558 __ cmppsnle(left, right); 3558 __ cmppsnle(left, right);
(...skipping 13 matching lines...) Expand all
3572 } 3572 }
3573 3573
3574 3574
3575 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { 3575 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const {
3576 const intptr_t kNumInputs = 2; 3576 const intptr_t kNumInputs = 2;
3577 const intptr_t kNumTemps = 0; 3577 const intptr_t kNumTemps = 0;
3578 LocationSummary* summary = 3578 LocationSummary* summary =
3579 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3579 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3580 summary->set_in(0, Location::RequiresFpuRegister()); 3580 summary->set_in(0, Location::RequiresFpuRegister());
3581 summary->set_in(1, Location::RequiresFpuRegister()); 3581 summary->set_in(1, Location::RequiresFpuRegister());
3582 summary->set_out(Location::SameAsFirstInput()); 3582 summary->set_out(0, Location::SameAsFirstInput());
3583 return summary; 3583 return summary;
3584 } 3584 }
3585 3585
3586 3586
3587 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3587 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3588 XmmRegister left = locs()->in(0).fpu_reg(); 3588 XmmRegister left = locs()->in(0).fpu_reg();
3589 XmmRegister right = locs()->in(1).fpu_reg(); 3589 XmmRegister right = locs()->in(1).fpu_reg();
3590 3590
3591 ASSERT(locs()->out().fpu_reg() == left); 3591 ASSERT(locs()->out(0).fpu_reg() == left);
3592 3592
3593 switch (op_kind()) { 3593 switch (op_kind()) {
3594 case MethodRecognizer::kFloat32x4Min: 3594 case MethodRecognizer::kFloat32x4Min:
3595 __ minps(left, right); 3595 __ minps(left, right);
3596 break; 3596 break;
3597 case MethodRecognizer::kFloat32x4Max: 3597 case MethodRecognizer::kFloat32x4Max:
3598 __ maxps(left, right); 3598 __ maxps(left, right);
3599 break; 3599 break;
3600 default: UNREACHABLE(); 3600 default: UNREACHABLE();
3601 } 3601 }
3602 } 3602 }
3603 3603
3604 3604
3605 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { 3605 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const {
3606 const intptr_t kNumInputs = 2; 3606 const intptr_t kNumInputs = 2;
3607 const intptr_t kNumTemps = 0; 3607 const intptr_t kNumTemps = 0;
3608 LocationSummary* summary = 3608 LocationSummary* summary =
3609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3610 summary->set_in(0, Location::RequiresFpuRegister()); 3610 summary->set_in(0, Location::RequiresFpuRegister());
3611 summary->set_in(1, Location::RequiresFpuRegister()); 3611 summary->set_in(1, Location::RequiresFpuRegister());
3612 summary->set_out(Location::SameAsFirstInput()); 3612 summary->set_out(0, Location::SameAsFirstInput());
3613 return summary; 3613 return summary;
3614 } 3614 }
3615 3615
3616 3616
3617 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3617 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3618 XmmRegister left = locs()->in(0).fpu_reg(); 3618 XmmRegister left = locs()->in(0).fpu_reg();
3619 XmmRegister right = locs()->in(1).fpu_reg(); 3619 XmmRegister right = locs()->in(1).fpu_reg();
3620 3620
3621 ASSERT(locs()->out().fpu_reg() == left); 3621 ASSERT(locs()->out(0).fpu_reg() == left);
3622 3622
3623 switch (op_kind()) { 3623 switch (op_kind()) {
3624 case MethodRecognizer::kFloat32x4Scale: 3624 case MethodRecognizer::kFloat32x4Scale:
3625 __ cvtsd2ss(left, left); 3625 __ cvtsd2ss(left, left);
3626 __ shufps(left, left, Immediate(0x00)); 3626 __ shufps(left, left, Immediate(0x00));
3627 __ mulps(left, right); 3627 __ mulps(left, right);
3628 break; 3628 break;
3629 default: UNREACHABLE(); 3629 default: UNREACHABLE();
3630 } 3630 }
3631 } 3631 }
3632 3632
3633 3633
3634 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { 3634 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const {
3635 const intptr_t kNumInputs = 1; 3635 const intptr_t kNumInputs = 1;
3636 const intptr_t kNumTemps = 0; 3636 const intptr_t kNumTemps = 0;
3637 LocationSummary* summary = 3637 LocationSummary* summary =
3638 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3638 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3639 summary->set_in(0, Location::RequiresFpuRegister()); 3639 summary->set_in(0, Location::RequiresFpuRegister());
3640 summary->set_out(Location::SameAsFirstInput()); 3640 summary->set_out(0, Location::SameAsFirstInput());
3641 return summary; 3641 return summary;
3642 } 3642 }
3643 3643
3644 3644
3645 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3645 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3646 XmmRegister left = locs()->in(0).fpu_reg(); 3646 XmmRegister left = locs()->in(0).fpu_reg();
3647 3647
3648 ASSERT(locs()->out().fpu_reg() == left); 3648 ASSERT(locs()->out(0).fpu_reg() == left);
3649 3649
3650 switch (op_kind()) { 3650 switch (op_kind()) {
3651 case MethodRecognizer::kFloat32x4Sqrt: 3651 case MethodRecognizer::kFloat32x4Sqrt:
3652 __ sqrtps(left); 3652 __ sqrtps(left);
3653 break; 3653 break;
3654 case MethodRecognizer::kFloat32x4Reciprocal: 3654 case MethodRecognizer::kFloat32x4Reciprocal:
3655 __ reciprocalps(left); 3655 __ reciprocalps(left);
3656 break; 3656 break;
3657 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 3657 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
3658 __ rsqrtps(left); 3658 __ rsqrtps(left);
3659 break; 3659 break;
3660 default: UNREACHABLE(); 3660 default: UNREACHABLE();
3661 } 3661 }
3662 } 3662 }
3663 3663
3664 3664
3665 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { 3665 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const {
3666 const intptr_t kNumInputs = 1; 3666 const intptr_t kNumInputs = 1;
3667 const intptr_t kNumTemps = 0; 3667 const intptr_t kNumTemps = 0;
3668 LocationSummary* summary = 3668 LocationSummary* summary =
3669 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3669 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3670 summary->set_in(0, Location::RequiresFpuRegister()); 3670 summary->set_in(0, Location::RequiresFpuRegister());
3671 summary->set_out(Location::SameAsFirstInput()); 3671 summary->set_out(0, Location::SameAsFirstInput());
3672 return summary; 3672 return summary;
3673 } 3673 }
3674 3674
3675 3675
3676 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3676 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3677 XmmRegister left = locs()->in(0).fpu_reg(); 3677 XmmRegister left = locs()->in(0).fpu_reg();
3678 3678
3679 ASSERT(locs()->out().fpu_reg() == left); 3679 ASSERT(locs()->out(0).fpu_reg() == left);
3680 switch (op_kind()) { 3680 switch (op_kind()) {
3681 case MethodRecognizer::kFloat32x4Negate: 3681 case MethodRecognizer::kFloat32x4Negate:
3682 __ negateps(left); 3682 __ negateps(left);
3683 break; 3683 break;
3684 case MethodRecognizer::kFloat32x4Absolute: 3684 case MethodRecognizer::kFloat32x4Absolute:
3685 __ absps(left); 3685 __ absps(left);
3686 break; 3686 break;
3687 default: UNREACHABLE(); 3687 default: UNREACHABLE();
3688 } 3688 }
3689 } 3689 }
3690 3690
3691 3691
3692 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { 3692 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const {
3693 const intptr_t kNumInputs = 3; 3693 const intptr_t kNumInputs = 3;
3694 const intptr_t kNumTemps = 0; 3694 const intptr_t kNumTemps = 0;
3695 LocationSummary* summary = 3695 LocationSummary* summary =
3696 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3696 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3697 summary->set_in(0, Location::RequiresFpuRegister()); 3697 summary->set_in(0, Location::RequiresFpuRegister());
3698 summary->set_in(1, Location::RequiresFpuRegister()); 3698 summary->set_in(1, Location::RequiresFpuRegister());
3699 summary->set_in(2, Location::RequiresFpuRegister()); 3699 summary->set_in(2, Location::RequiresFpuRegister());
3700 summary->set_out(Location::SameAsFirstInput()); 3700 summary->set_out(0, Location::SameAsFirstInput());
3701 return summary; 3701 return summary;
3702 } 3702 }
3703 3703
3704 3704
3705 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3705 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3706 XmmRegister left = locs()->in(0).fpu_reg(); 3706 XmmRegister left = locs()->in(0).fpu_reg();
3707 XmmRegister lower = locs()->in(1).fpu_reg(); 3707 XmmRegister lower = locs()->in(1).fpu_reg();
3708 XmmRegister upper = locs()->in(2).fpu_reg(); 3708 XmmRegister upper = locs()->in(2).fpu_reg();
3709 ASSERT(locs()->out().fpu_reg() == left); 3709 ASSERT(locs()->out(0).fpu_reg() == left);
3710 __ minps(left, upper); 3710 __ minps(left, upper);
3711 __ maxps(left, lower); 3711 __ maxps(left, lower);
3712 } 3712 }
3713 3713
3714 3714
3715 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { 3715 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const {
3716 const intptr_t kNumInputs = 2; 3716 const intptr_t kNumInputs = 2;
3717 const intptr_t kNumTemps = 0; 3717 const intptr_t kNumTemps = 0;
3718 LocationSummary* summary = 3718 LocationSummary* summary =
3719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3720 summary->set_in(0, Location::RequiresFpuRegister()); 3720 summary->set_in(0, Location::RequiresFpuRegister());
3721 summary->set_in(1, Location::RequiresFpuRegister()); 3721 summary->set_in(1, Location::RequiresFpuRegister());
3722 summary->set_out(Location::SameAsFirstInput()); 3722 summary->set_out(0, Location::SameAsFirstInput());
3723 return summary; 3723 return summary;
3724 } 3724 }
3725 3725
3726 3726
3727 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3727 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3728 XmmRegister replacement = locs()->in(0).fpu_reg(); 3728 XmmRegister replacement = locs()->in(0).fpu_reg();
3729 XmmRegister value = locs()->in(1).fpu_reg(); 3729 XmmRegister value = locs()->in(1).fpu_reg();
3730 3730
3731 ASSERT(locs()->out().fpu_reg() == replacement); 3731 ASSERT(locs()->out(0).fpu_reg() == replacement);
3732 3732
3733 switch (op_kind()) { 3733 switch (op_kind()) {
3734 case MethodRecognizer::kFloat32x4WithX: 3734 case MethodRecognizer::kFloat32x4WithX:
3735 __ cvtsd2ss(replacement, replacement); 3735 __ cvtsd2ss(replacement, replacement);
3736 __ AddImmediate(RSP, Immediate(-16), PP); 3736 __ AddImmediate(RSP, Immediate(-16), PP);
3737 // Move value to stack. 3737 // Move value to stack.
3738 __ movups(Address(RSP, 0), value); 3738 __ movups(Address(RSP, 0), value);
3739 // Write over X value. 3739 // Write over X value.
3740 __ movss(Address(RSP, 0), replacement); 3740 __ movss(Address(RSP, 0), replacement);
3741 // Move updated value into output register. 3741 // Move updated value into output register.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3779 } 3779 }
3780 } 3780 }
3781 3781
3782 3782
3783 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { 3783 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const {
3784 const intptr_t kNumInputs = 1; 3784 const intptr_t kNumInputs = 1;
3785 const intptr_t kNumTemps = 0; 3785 const intptr_t kNumTemps = 0;
3786 LocationSummary* summary = 3786 LocationSummary* summary =
3787 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3787 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3788 summary->set_in(0, Location::RequiresFpuRegister()); 3788 summary->set_in(0, Location::RequiresFpuRegister());
3789 summary->set_out(Location::SameAsFirstInput()); 3789 summary->set_out(0, Location::SameAsFirstInput());
3790 return summary; 3790 return summary;
3791 } 3791 }
3792 3792
3793 3793
3794 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3794 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3795 // NOP. 3795 // NOP.
3796 } 3796 }
3797 3797
3798 3798
3799 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { 3799 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const {
3800 const intptr_t kNumInputs = 1; 3800 const intptr_t kNumInputs = 1;
3801 const intptr_t kNumTemps = 0; 3801 const intptr_t kNumTemps = 0;
3802 LocationSummary* summary = 3802 LocationSummary* summary =
3803 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3803 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3804 summary->set_in(0, Location::RequiresFpuRegister()); 3804 summary->set_in(0, Location::RequiresFpuRegister());
3805 summary->set_out(Location::SameAsFirstInput()); 3805 summary->set_out(0, Location::SameAsFirstInput());
3806 return summary; 3806 return summary;
3807 } 3807 }
3808 3808
3809 3809
3810 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3810 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3811 XmmRegister value = locs()->in(0).fpu_reg(); 3811 XmmRegister value = locs()->in(0).fpu_reg();
3812 3812
3813 ASSERT(locs()->out().fpu_reg() == value); 3813 ASSERT(locs()->out(0).fpu_reg() == value);
3814 switch (op_kind()) { 3814 switch (op_kind()) {
3815 case MethodRecognizer::kFloat64x2GetX: 3815 case MethodRecognizer::kFloat64x2GetX:
3816 // nop. 3816 // nop.
3817 break; 3817 break;
3818 case MethodRecognizer::kFloat64x2GetY: 3818 case MethodRecognizer::kFloat64x2GetY:
3819 __ shufpd(value, value, Immediate(0x33)); 3819 __ shufpd(value, value, Immediate(0x33));
3820 break; 3820 break;
3821 default: UNREACHABLE(); 3821 default: UNREACHABLE();
3822 } 3822 }
3823 } 3823 }
3824 3824
3825 3825
3826 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { 3826 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const {
3827 const intptr_t kNumInputs = 0; 3827 const intptr_t kNumInputs = 0;
3828 const intptr_t kNumTemps = 0; 3828 const intptr_t kNumTemps = 0;
3829 LocationSummary* summary = 3829 LocationSummary* summary =
3830 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3830 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3831 summary->set_out(Location::RequiresFpuRegister()); 3831 summary->set_out(0, Location::RequiresFpuRegister());
3832 return summary; 3832 return summary;
3833 } 3833 }
3834 3834
3835 3835
3836 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3836 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3837 XmmRegister value = locs()->out().fpu_reg(); 3837 XmmRegister value = locs()->out(0).fpu_reg();
3838 __ xorpd(value, value); 3838 __ xorpd(value, value);
3839 } 3839 }
3840 3840
3841 3841
3842 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { 3842 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const {
3843 const intptr_t kNumInputs = 1; 3843 const intptr_t kNumInputs = 1;
3844 const intptr_t kNumTemps = 0; 3844 const intptr_t kNumTemps = 0;
3845 LocationSummary* summary = 3845 LocationSummary* summary =
3846 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3846 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3847 summary->set_in(0, Location::RequiresFpuRegister()); 3847 summary->set_in(0, Location::RequiresFpuRegister());
3848 summary->set_out(Location::SameAsFirstInput()); 3848 summary->set_out(0, Location::SameAsFirstInput());
3849 return summary; 3849 return summary;
3850 } 3850 }
3851 3851
3852 3852
3853 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3853 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3854 XmmRegister value = locs()->out().fpu_reg(); 3854 XmmRegister value = locs()->out(0).fpu_reg();
3855 __ shufpd(value, value, Immediate(0x0)); 3855 __ shufpd(value, value, Immediate(0x0));
3856 } 3856 }
3857 3857
3858 3858
3859 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( 3859 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary(
3860 bool opt) const { 3860 bool opt) const {
3861 const intptr_t kNumInputs = 2; 3861 const intptr_t kNumInputs = 2;
3862 const intptr_t kNumTemps = 0; 3862 const intptr_t kNumTemps = 0;
3863 LocationSummary* summary = 3863 LocationSummary* summary =
3864 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3864 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3865 summary->set_in(0, Location::RequiresFpuRegister()); 3865 summary->set_in(0, Location::RequiresFpuRegister());
3866 summary->set_in(1, Location::RequiresFpuRegister()); 3866 summary->set_in(1, Location::RequiresFpuRegister());
3867 summary->set_out(Location::SameAsFirstInput()); 3867 summary->set_out(0, Location::SameAsFirstInput());
3868 return summary; 3868 return summary;
3869 } 3869 }
3870 3870
3871 3871
3872 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3872 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3873 XmmRegister v0 = locs()->in(0).fpu_reg(); 3873 XmmRegister v0 = locs()->in(0).fpu_reg();
3874 XmmRegister v1 = locs()->in(1).fpu_reg(); 3874 XmmRegister v1 = locs()->in(1).fpu_reg();
3875 ASSERT(v0 == locs()->out().fpu_reg()); 3875 ASSERT(v0 == locs()->out(0).fpu_reg());
3876 __ AddImmediate(RSP, Immediate(-16), PP); 3876 __ AddImmediate(RSP, Immediate(-16), PP);
3877 __ movsd(Address(RSP, 0), v0); 3877 __ movsd(Address(RSP, 0), v0);
3878 __ movsd(Address(RSP, 8), v1); 3878 __ movsd(Address(RSP, 8), v1);
3879 __ movups(v0, Address(RSP, 0)); 3879 __ movups(v0, Address(RSP, 0));
3880 __ AddImmediate(RSP, Immediate(16), PP); 3880 __ AddImmediate(RSP, Immediate(16), PP);
3881 } 3881 }
3882 3882
3883 3883
3884 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( 3884 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary(
3885 bool opt) const { 3885 bool opt) const {
3886 const intptr_t kNumInputs = 1; 3886 const intptr_t kNumInputs = 1;
3887 const intptr_t kNumTemps = 0; 3887 const intptr_t kNumTemps = 0;
3888 LocationSummary* summary = 3888 LocationSummary* summary =
3889 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3889 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3890 summary->set_in(0, Location::RequiresFpuRegister()); 3890 summary->set_in(0, Location::RequiresFpuRegister());
3891 summary->set_out(Location::SameAsFirstInput()); 3891 summary->set_out(0, Location::SameAsFirstInput());
3892 return summary; 3892 return summary;
3893 } 3893 }
3894 3894
3895 3895
3896 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3896 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3897 XmmRegister value = locs()->out().fpu_reg(); 3897 XmmRegister value = locs()->out(0).fpu_reg();
3898 __ cvtpd2ps(value, value); 3898 __ cvtpd2ps(value, value);
3899 } 3899 }
3900 3900
3901 3901
3902 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( 3902 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary(
3903 bool opt) const { 3903 bool opt) const {
3904 const intptr_t kNumInputs = 1; 3904 const intptr_t kNumInputs = 1;
3905 const intptr_t kNumTemps = 0; 3905 const intptr_t kNumTemps = 0;
3906 LocationSummary* summary = 3906 LocationSummary* summary =
3907 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3907 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3908 summary->set_in(0, Location::RequiresFpuRegister()); 3908 summary->set_in(0, Location::RequiresFpuRegister());
3909 summary->set_out(Location::SameAsFirstInput()); 3909 summary->set_out(0, Location::SameAsFirstInput());
3910 return summary; 3910 return summary;
3911 } 3911 }
3912 3912
3913 3913
3914 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3914 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3915 XmmRegister value = locs()->out().fpu_reg(); 3915 XmmRegister value = locs()->out(0).fpu_reg();
3916 __ cvtps2pd(value, value); 3916 __ cvtps2pd(value, value);
3917 } 3917 }
3918 3918
3919 3919
3920 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const { 3920 LocationSummary* Float64x2ZeroArgInstr::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 if (representation() == kTagged) { 3926 if (representation() == kTagged) {
3927 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask); 3927 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask);
3928 summary->set_out(Location::RequiresRegister()); 3928 summary->set_out(0, Location::RequiresRegister());
3929 } else { 3929 } else {
3930 ASSERT(representation() == kUnboxedFloat64x2); 3930 ASSERT(representation() == kUnboxedFloat64x2);
3931 summary->set_out(Location::SameAsFirstInput()); 3931 summary->set_out(0, Location::SameAsFirstInput());
3932 } 3932 }
3933 return summary; 3933 return summary;
3934 } 3934 }
3935 3935
3936 3936
3937 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3937 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3938 XmmRegister left = locs()->in(0).fpu_reg(); 3938 XmmRegister left = locs()->in(0).fpu_reg();
3939 3939
3940 ASSERT((op_kind() == MethodRecognizer::kFloat64x2GetSignMask) || 3940 ASSERT((op_kind() == MethodRecognizer::kFloat64x2GetSignMask) ||
3941 (locs()->out().fpu_reg() == left)); 3941 (locs()->out(0).fpu_reg() == left));
3942 3942
3943 switch (op_kind()) { 3943 switch (op_kind()) {
3944 case MethodRecognizer::kFloat64x2Negate: 3944 case MethodRecognizer::kFloat64x2Negate:
3945 __ negatepd(left); 3945 __ negatepd(left);
3946 break; 3946 break;
3947 case MethodRecognizer::kFloat64x2Abs: 3947 case MethodRecognizer::kFloat64x2Abs:
3948 __ abspd(left); 3948 __ abspd(left);
3949 break; 3949 break;
3950 case MethodRecognizer::kFloat64x2Sqrt: 3950 case MethodRecognizer::kFloat64x2Sqrt:
3951 __ sqrtpd(left); 3951 __ sqrtpd(left);
3952 break; 3952 break;
3953 case MethodRecognizer::kFloat64x2GetSignMask: 3953 case MethodRecognizer::kFloat64x2GetSignMask:
3954 __ movmskpd(locs()->out().reg(), left); 3954 __ movmskpd(locs()->out(0).reg(), left);
3955 __ SmiTag(locs()->out().reg()); 3955 __ SmiTag(locs()->out(0).reg());
3956 break; 3956 break;
3957 default: UNREACHABLE(); 3957 default: UNREACHABLE();
3958 } 3958 }
3959 } 3959 }
3960 3960
3961 3961
3962 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const { 3962 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const {
3963 const intptr_t kNumInputs = 2; 3963 const intptr_t kNumInputs = 2;
3964 const intptr_t kNumTemps = 0; 3964 const intptr_t kNumTemps = 0;
3965 LocationSummary* summary = 3965 LocationSummary* summary =
3966 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3966 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3967 summary->set_in(0, Location::RequiresFpuRegister()); 3967 summary->set_in(0, Location::RequiresFpuRegister());
3968 summary->set_in(1, Location::RequiresFpuRegister()); 3968 summary->set_in(1, Location::RequiresFpuRegister());
3969 summary->set_out(Location::SameAsFirstInput()); 3969 summary->set_out(0, Location::SameAsFirstInput());
3970 return summary; 3970 return summary;
3971 } 3971 }
3972 3972
3973 3973
3974 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3974 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3975 XmmRegister left = locs()->in(0).fpu_reg(); 3975 XmmRegister left = locs()->in(0).fpu_reg();
3976 XmmRegister right = locs()->in(1).fpu_reg(); 3976 XmmRegister right = locs()->in(1).fpu_reg();
3977 ASSERT((locs()->out().fpu_reg() == left)); 3977 ASSERT((locs()->out(0).fpu_reg() == left));
3978 3978
3979 switch (op_kind()) { 3979 switch (op_kind()) {
3980 case MethodRecognizer::kFloat64x2Scale: 3980 case MethodRecognizer::kFloat64x2Scale:
3981 __ shufpd(right, right, Immediate(0x00)); 3981 __ shufpd(right, right, Immediate(0x00));
3982 __ mulpd(left, right); 3982 __ mulpd(left, right);
3983 break; 3983 break;
3984 case MethodRecognizer::kFloat64x2WithX: 3984 case MethodRecognizer::kFloat64x2WithX:
3985 __ subq(RSP, Immediate(16)); 3985 __ subq(RSP, Immediate(16));
3986 // Move value to stack. 3986 // Move value to stack.
3987 __ movups(Address(RSP, 0), left); 3987 __ movups(Address(RSP, 0), left);
(...skipping 28 matching lines...) Expand all
4016 bool opt) const { 4016 bool opt) const {
4017 const intptr_t kNumInputs = 4; 4017 const intptr_t kNumInputs = 4;
4018 const intptr_t kNumTemps = 1; 4018 const intptr_t kNumTemps = 1;
4019 LocationSummary* summary = 4019 LocationSummary* summary =
4020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4021 summary->set_in(0, Location::RequiresRegister()); 4021 summary->set_in(0, Location::RequiresRegister());
4022 summary->set_in(1, Location::RequiresRegister()); 4022 summary->set_in(1, Location::RequiresRegister());
4023 summary->set_in(2, Location::RequiresRegister()); 4023 summary->set_in(2, Location::RequiresRegister());
4024 summary->set_in(3, Location::RequiresRegister()); 4024 summary->set_in(3, Location::RequiresRegister());
4025 summary->set_temp(0, Location::RequiresRegister()); 4025 summary->set_temp(0, Location::RequiresRegister());
4026 summary->set_out(Location::RequiresFpuRegister()); 4026 summary->set_out(0, Location::RequiresFpuRegister());
4027 return summary; 4027 return summary;
4028 } 4028 }
4029 4029
4030 4030
4031 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4031 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4032 Register v0 = locs()->in(0).reg(); 4032 Register v0 = locs()->in(0).reg();
4033 Register v1 = locs()->in(1).reg(); 4033 Register v1 = locs()->in(1).reg();
4034 Register v2 = locs()->in(2).reg(); 4034 Register v2 = locs()->in(2).reg();
4035 Register v3 = locs()->in(3).reg(); 4035 Register v3 = locs()->in(3).reg();
4036 Register temp = locs()->temp(0).reg(); 4036 Register temp = locs()->temp(0).reg();
4037 XmmRegister result = locs()->out().fpu_reg(); 4037 XmmRegister result = locs()->out(0).fpu_reg();
4038 Label x_false, x_done; 4038 Label x_false, x_done;
4039 Label y_false, y_done; 4039 Label y_false, y_done;
4040 Label z_false, z_done; 4040 Label z_false, z_done;
4041 Label w_false, w_done; 4041 Label w_false, w_done;
4042 __ AddImmediate(RSP, Immediate(-16), PP); 4042 __ AddImmediate(RSP, Immediate(-16), PP);
4043 4043
4044 __ CompareObject(v0, Bool::True(), PP); 4044 __ CompareObject(v0, Bool::True(), PP);
4045 __ j(NOT_EQUAL, &x_false); 4045 __ j(NOT_EQUAL, &x_false);
4046 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); 4046 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
4047 __ jmp(&x_done); 4047 __ jmp(&x_done);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4081 __ AddImmediate(RSP, Immediate(16), PP); 4081 __ AddImmediate(RSP, Immediate(16), PP);
4082 } 4082 }
4083 4083
4084 4084
4085 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { 4085 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const {
4086 const intptr_t kNumInputs = 1; 4086 const intptr_t kNumInputs = 1;
4087 const intptr_t kNumTemps = 0; 4087 const intptr_t kNumTemps = 0;
4088 LocationSummary* summary = 4088 LocationSummary* summary =
4089 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4089 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4090 summary->set_in(0, Location::RequiresFpuRegister()); 4090 summary->set_in(0, Location::RequiresFpuRegister());
4091 summary->set_out(Location::RequiresRegister()); 4091 summary->set_out(0, Location::RequiresRegister());
4092 return summary; 4092 return summary;
4093 } 4093 }
4094 4094
4095 4095
4096 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4096 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4097 XmmRegister value = locs()->in(0).fpu_reg(); 4097 XmmRegister value = locs()->in(0).fpu_reg();
4098 Register result = locs()->out().reg(); 4098 Register result = locs()->out(0).reg();
4099 Label done; 4099 Label done;
4100 Label non_zero; 4100 Label non_zero;
4101 __ AddImmediate(RSP, Immediate(-16), PP); 4101 __ AddImmediate(RSP, Immediate(-16), PP);
4102 // Move value to stack. 4102 // Move value to stack.
4103 __ movups(Address(RSP, 0), value); 4103 __ movups(Address(RSP, 0), value);
4104 switch (op_kind()) { 4104 switch (op_kind()) {
4105 case MethodRecognizer::kInt32x4GetFlagX: 4105 case MethodRecognizer::kInt32x4GetFlagX:
4106 __ movl(result, Address(RSP, 0)); 4106 __ movl(result, Address(RSP, 0));
4107 break; 4107 break;
4108 case MethodRecognizer::kInt32x4GetFlagY: 4108 case MethodRecognizer::kInt32x4GetFlagY:
(...skipping 20 matching lines...) Expand all
4129 4129
4130 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { 4130 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const {
4131 const intptr_t kNumInputs = 3; 4131 const intptr_t kNumInputs = 3;
4132 const intptr_t kNumTemps = 1; 4132 const intptr_t kNumTemps = 1;
4133 LocationSummary* summary = 4133 LocationSummary* summary =
4134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4135 summary->set_in(0, Location::RequiresFpuRegister()); 4135 summary->set_in(0, Location::RequiresFpuRegister());
4136 summary->set_in(1, Location::RequiresFpuRegister()); 4136 summary->set_in(1, Location::RequiresFpuRegister());
4137 summary->set_in(2, Location::RequiresFpuRegister()); 4137 summary->set_in(2, Location::RequiresFpuRegister());
4138 summary->set_temp(0, Location::RequiresFpuRegister()); 4138 summary->set_temp(0, Location::RequiresFpuRegister());
4139 summary->set_out(Location::SameAsFirstInput()); 4139 summary->set_out(0, Location::SameAsFirstInput());
4140 return summary; 4140 return summary;
4141 } 4141 }
4142 4142
4143 4143
4144 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4144 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4145 XmmRegister mask = locs()->in(0).fpu_reg(); 4145 XmmRegister mask = locs()->in(0).fpu_reg();
4146 XmmRegister trueValue = locs()->in(1).fpu_reg(); 4146 XmmRegister trueValue = locs()->in(1).fpu_reg();
4147 XmmRegister falseValue = locs()->in(2).fpu_reg(); 4147 XmmRegister falseValue = locs()->in(2).fpu_reg();
4148 XmmRegister out = locs()->out().fpu_reg(); 4148 XmmRegister out = locs()->out(0).fpu_reg();
4149 XmmRegister temp = locs()->temp(0).fpu_reg(); 4149 XmmRegister temp = locs()->temp(0).fpu_reg();
4150 ASSERT(out == mask); 4150 ASSERT(out == mask);
4151 // Copy mask. 4151 // Copy mask.
4152 __ movaps(temp, mask); 4152 __ movaps(temp, mask);
4153 // Invert it. 4153 // Invert it.
4154 __ notps(temp); 4154 __ notps(temp);
4155 // mask = mask & trueValue. 4155 // mask = mask & trueValue.
4156 __ andps(mask, trueValue); 4156 __ andps(mask, trueValue);
4157 // temp = temp & falseValue. 4157 // temp = temp & falseValue.
4158 __ andps(temp, falseValue); 4158 __ andps(temp, falseValue);
4159 // out = mask | temp. 4159 // out = mask | temp.
4160 __ orps(mask, temp); 4160 __ orps(mask, temp);
4161 } 4161 }
4162 4162
4163 4163
4164 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { 4164 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const {
4165 const intptr_t kNumInputs = 2; 4165 const intptr_t kNumInputs = 2;
4166 const intptr_t kNumTemps = 1; 4166 const intptr_t kNumTemps = 1;
4167 LocationSummary* summary = 4167 LocationSummary* summary =
4168 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4168 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4169 summary->set_in(0, Location::RequiresFpuRegister()); 4169 summary->set_in(0, Location::RequiresFpuRegister());
4170 summary->set_in(1, Location::RequiresRegister()); 4170 summary->set_in(1, Location::RequiresRegister());
4171 summary->set_temp(0, Location::RequiresRegister()); 4171 summary->set_temp(0, Location::RequiresRegister());
4172 summary->set_out(Location::SameAsFirstInput()); 4172 summary->set_out(0, Location::SameAsFirstInput());
4173 return summary; 4173 return summary;
4174 } 4174 }
4175 4175
4176 4176
4177 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4177 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4178 XmmRegister mask = locs()->in(0).fpu_reg(); 4178 XmmRegister mask = locs()->in(0).fpu_reg();
4179 Register flag = locs()->in(1).reg(); 4179 Register flag = locs()->in(1).reg();
4180 Register temp = locs()->temp(0).reg(); 4180 Register temp = locs()->temp(0).reg();
4181 ASSERT(mask == locs()->out().fpu_reg()); 4181 ASSERT(mask == locs()->out(0).fpu_reg());
4182 __ AddImmediate(RSP, Immediate(-16), PP); 4182 __ AddImmediate(RSP, Immediate(-16), PP);
4183 // Copy mask to stack. 4183 // Copy mask to stack.
4184 __ movups(Address(RSP, 0), mask); 4184 __ movups(Address(RSP, 0), mask);
4185 Label falsePath, exitPath; 4185 Label falsePath, exitPath;
4186 __ CompareObject(flag, Bool::True(), PP); 4186 __ CompareObject(flag, Bool::True(), PP);
4187 __ j(NOT_EQUAL, &falsePath); 4187 __ j(NOT_EQUAL, &falsePath);
4188 switch (op_kind()) { 4188 switch (op_kind()) {
4189 case MethodRecognizer::kInt32x4WithFlagX: 4189 case MethodRecognizer::kInt32x4WithFlagX:
4190 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP); 4190 __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
4191 __ movl(Address(RSP, 0), temp); 4191 __ movl(Address(RSP, 0), temp);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4226 __ AddImmediate(RSP, Immediate(16), PP); 4226 __ AddImmediate(RSP, Immediate(16), PP);
4227 } 4227 }
4228 4228
4229 4229
4230 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { 4230 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const {
4231 const intptr_t kNumInputs = 1; 4231 const intptr_t kNumInputs = 1;
4232 const intptr_t kNumTemps = 0; 4232 const intptr_t kNumTemps = 0;
4233 LocationSummary* summary = 4233 LocationSummary* summary =
4234 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4234 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4235 summary->set_in(0, Location::RequiresFpuRegister()); 4235 summary->set_in(0, Location::RequiresFpuRegister());
4236 summary->set_out(Location::SameAsFirstInput()); 4236 summary->set_out(0, Location::SameAsFirstInput());
4237 return summary; 4237 return summary;
4238 } 4238 }
4239 4239
4240 4240
4241 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4241 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4242 // NOP. 4242 // NOP.
4243 } 4243 }
4244 4244
4245 4245
4246 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { 4246 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const {
4247 const intptr_t kNumInputs = 2; 4247 const intptr_t kNumInputs = 2;
4248 const intptr_t kNumTemps = 0; 4248 const intptr_t kNumTemps = 0;
4249 LocationSummary* summary = 4249 LocationSummary* summary =
4250 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4250 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4251 summary->set_in(0, Location::RequiresFpuRegister()); 4251 summary->set_in(0, Location::RequiresFpuRegister());
4252 summary->set_in(1, Location::RequiresFpuRegister()); 4252 summary->set_in(1, Location::RequiresFpuRegister());
4253 summary->set_out(Location::SameAsFirstInput()); 4253 summary->set_out(0, Location::SameAsFirstInput());
4254 return summary; 4254 return summary;
4255 } 4255 }
4256 4256
4257 4257
4258 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4258 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4259 XmmRegister left = locs()->in(0).fpu_reg(); 4259 XmmRegister left = locs()->in(0).fpu_reg();
4260 XmmRegister right = locs()->in(1).fpu_reg(); 4260 XmmRegister right = locs()->in(1).fpu_reg();
4261 ASSERT(left == locs()->out().fpu_reg()); 4261 ASSERT(left == locs()->out(0).fpu_reg());
4262 switch (op_kind()) { 4262 switch (op_kind()) {
4263 case Token::kBIT_AND: { 4263 case Token::kBIT_AND: {
4264 __ andps(left, right); 4264 __ andps(left, right);
4265 break; 4265 break;
4266 } 4266 }
4267 case Token::kBIT_OR: { 4267 case Token::kBIT_OR: {
4268 __ orps(left, right); 4268 __ orps(left, right);
4269 break; 4269 break;
4270 } 4270 }
4271 case Token::kBIT_XOR: { 4271 case Token::kBIT_XOR: {
(...skipping 19 matching lines...) Expand all
4291 // currently we can't specify these registers because ParallelMoveResolver 4291 // currently we can't specify these registers because ParallelMoveResolver
4292 // assumes that XMM0 is free at all times. 4292 // assumes that XMM0 is free at all times.
4293 // TODO(vegorov): allow XMM0 to be used. 4293 // TODO(vegorov): allow XMM0 to be used.
4294 const intptr_t kNumTemps = 1; 4294 const intptr_t kNumTemps = 1;
4295 LocationSummary* summary = 4295 LocationSummary* summary =
4296 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4296 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
4297 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4297 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4298 // R13 is chosen because it is callee saved so we do not need to back it 4298 // R13 is chosen because it is callee saved so we do not need to back it
4299 // up before calling into the runtime. 4299 // up before calling into the runtime.
4300 summary->set_temp(0, Location::RegisterLocation(R13)); 4300 summary->set_temp(0, Location::RegisterLocation(R13));
4301 summary->set_out(Location::FpuRegisterLocation(XMM1)); 4301 summary->set_out(0, Location::FpuRegisterLocation(XMM1));
4302 return summary; 4302 return summary;
4303 } 4303 }
4304 ASSERT(kind() == MethodRecognizer::kMathSqrt); 4304 ASSERT(kind() == MethodRecognizer::kMathSqrt);
4305 const intptr_t kNumInputs = 1; 4305 const intptr_t kNumInputs = 1;
4306 const intptr_t kNumTemps = 0; 4306 const intptr_t kNumTemps = 0;
4307 LocationSummary* summary = 4307 LocationSummary* summary =
4308 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4308 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4309 summary->set_in(0, Location::RequiresFpuRegister()); 4309 summary->set_in(0, Location::RequiresFpuRegister());
4310 summary->set_out(Location::RequiresFpuRegister()); 4310 summary->set_out(0, Location::RequiresFpuRegister());
4311 return summary; 4311 return summary;
4312 } 4312 }
4313 4313
4314 4314
4315 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4315 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4316 if (kind() == MethodRecognizer::kMathSqrt) { 4316 if (kind() == MethodRecognizer::kMathSqrt) {
4317 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4317 __ sqrtsd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4318 } else { 4318 } else {
4319 ASSERT((kind() == MethodRecognizer::kMathSin) || 4319 ASSERT((kind() == MethodRecognizer::kMathSin) ||
4320 (kind() == MethodRecognizer::kMathCos)); 4320 (kind() == MethodRecognizer::kMathCos));
4321 // Save RSP. 4321 // Save RSP.
4322 __ movq(locs()->temp(0).reg(), RSP); 4322 __ movq(locs()->temp(0).reg(), RSP);
4323 __ ReserveAlignedFrameSpace(0); 4323 __ ReserveAlignedFrameSpace(0);
4324 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4324 __ movaps(XMM0, locs()->in(0).fpu_reg());
4325 __ CallRuntime(TargetFunction(), InputCount()); 4325 __ CallRuntime(TargetFunction(), InputCount());
4326 __ movaps(locs()->out().fpu_reg(), XMM0); 4326 __ movaps(locs()->out(0).fpu_reg(), XMM0);
4327 // Restore RSP. 4327 // Restore RSP.
4328 __ movq(RSP, locs()->temp(0).reg()); 4328 __ movq(RSP, locs()->temp(0).reg());
4329 } 4329 }
4330 } 4330 }
4331 4331
4332 4332
4333 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { 4333 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
4334 const intptr_t kNumInputs = 1; 4334 const intptr_t kNumInputs = 1;
4335 return LocationSummary::Make(kNumInputs, 4335 return LocationSummary::Make(kNumInputs,
4336 Location::SameAsFirstInput(), 4336 Location::SameAsFirstInput(),
4337 LocationSummary::kNoCall); 4337 LocationSummary::kNoCall);
4338 } 4338 }
4339 4339
4340 4340
4341 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4341 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4342 Register value = locs()->in(0).reg(); 4342 Register value = locs()->in(0).reg();
4343 ASSERT(value == locs()->out().reg()); 4343 ASSERT(value == locs()->out(0).reg());
4344 switch (op_kind()) { 4344 switch (op_kind()) {
4345 case Token::kNEGATE: { 4345 case Token::kNEGATE: {
4346 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4346 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4347 kDeoptUnaryOp); 4347 kDeoptUnaryOp);
4348 __ negq(value); 4348 __ negq(value);
4349 __ j(OVERFLOW, deopt); 4349 __ j(OVERFLOW, deopt);
4350 if (FLAG_throw_on_javascript_int_overflow) { 4350 if (FLAG_throw_on_javascript_int_overflow) {
4351 EmitJavascriptOverflowCheck(compiler, range(), deopt, value); 4351 EmitJavascriptOverflowCheck(compiler, range(), deopt, value);
4352 } 4352 }
4353 break; 4353 break;
4354 } 4354 }
4355 case Token::kBIT_NOT: 4355 case Token::kBIT_NOT:
4356 __ notq(value); 4356 __ notq(value);
4357 // Remove inverted smi-tag. 4357 // Remove inverted smi-tag.
4358 __ AndImmediate(value, Immediate(~kSmiTagMask), PP); 4358 __ AndImmediate(value, Immediate(~kSmiTagMask), PP);
4359 break; 4359 break;
4360 default: 4360 default:
4361 UNREACHABLE(); 4361 UNREACHABLE();
4362 } 4362 }
4363 } 4363 }
4364 4364
4365 4365
4366 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 4366 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
4367 const intptr_t kNumInputs = 1; 4367 const intptr_t kNumInputs = 1;
4368 const intptr_t kNumTemps = 0; 4368 const intptr_t kNumTemps = 0;
4369 LocationSummary* summary = 4369 LocationSummary* summary =
4370 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4370 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4371 summary->set_in(0, Location::RequiresFpuRegister()); 4371 summary->set_in(0, Location::RequiresFpuRegister());
4372 summary->set_out(Location::SameAsFirstInput()); 4372 summary->set_out(0, Location::SameAsFirstInput());
4373 return summary; 4373 return summary;
4374 } 4374 }
4375 4375
4376 4376
4377 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4377 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4378 XmmRegister value = locs()->in(0).fpu_reg(); 4378 XmmRegister value = locs()->in(0).fpu_reg();
4379 ASSERT(locs()->out().fpu_reg() == value); 4379 ASSERT(locs()->out(0).fpu_reg() == value);
4380 __ DoubleNegate(value); 4380 __ DoubleNegate(value);
4381 } 4381 }
4382 4382
4383 4383
4384 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { 4384 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const {
4385 if (result_cid() == kDoubleCid) { 4385 if (result_cid() == kDoubleCid) {
4386 const intptr_t kNumInputs = 2; 4386 const intptr_t kNumInputs = 2;
4387 const intptr_t kNumTemps = 1; 4387 const intptr_t kNumTemps = 1;
4388 LocationSummary* summary = 4388 LocationSummary* summary =
4389 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4389 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4390 summary->set_in(0, Location::RequiresFpuRegister()); 4390 summary->set_in(0, Location::RequiresFpuRegister());
4391 summary->set_in(1, Location::RequiresFpuRegister()); 4391 summary->set_in(1, Location::RequiresFpuRegister());
4392 // Reuse the left register so that code can be made shorter. 4392 // Reuse the left register so that code can be made shorter.
4393 summary->set_out(Location::SameAsFirstInput()); 4393 summary->set_out(0, Location::SameAsFirstInput());
4394 summary->set_temp(0, Location::RequiresRegister()); 4394 summary->set_temp(0, Location::RequiresRegister());
4395 return summary; 4395 return summary;
4396 } 4396 }
4397 ASSERT(result_cid() == kSmiCid); 4397 ASSERT(result_cid() == kSmiCid);
4398 const intptr_t kNumInputs = 2; 4398 const intptr_t kNumInputs = 2;
4399 const intptr_t kNumTemps = 0; 4399 const intptr_t kNumTemps = 0;
4400 LocationSummary* summary = 4400 LocationSummary* summary =
4401 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4401 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4402 summary->set_in(0, Location::RequiresRegister()); 4402 summary->set_in(0, Location::RequiresRegister());
4403 summary->set_in(1, Location::RequiresRegister()); 4403 summary->set_in(1, Location::RequiresRegister());
4404 // Reuse the left register so that code can be made shorter. 4404 // Reuse the left register so that code can be made shorter.
4405 summary->set_out(Location::SameAsFirstInput()); 4405 summary->set_out(0, Location::SameAsFirstInput());
4406 return summary; 4406 return summary;
4407 } 4407 }
4408 4408
4409 4409
4410 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4410 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4411 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 4411 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
4412 (op_kind() == MethodRecognizer::kMathMax)); 4412 (op_kind() == MethodRecognizer::kMathMax));
4413 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); 4413 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
4414 if (result_cid() == kDoubleCid) { 4414 if (result_cid() == kDoubleCid) {
4415 Label done, returns_nan, are_equal; 4415 Label done, returns_nan, are_equal;
4416 XmmRegister left = locs()->in(0).fpu_reg(); 4416 XmmRegister left = locs()->in(0).fpu_reg();
4417 XmmRegister right = locs()->in(1).fpu_reg(); 4417 XmmRegister right = locs()->in(1).fpu_reg();
4418 XmmRegister result = locs()->out().fpu_reg(); 4418 XmmRegister result = locs()->out(0).fpu_reg();
4419 Register temp = locs()->temp(0).reg(); 4419 Register temp = locs()->temp(0).reg();
4420 __ comisd(left, right); 4420 __ comisd(left, right);
4421 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); 4421 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump);
4422 __ j(EQUAL, &are_equal, Assembler::kNearJump); 4422 __ j(EQUAL, &are_equal, Assembler::kNearJump);
4423 const Condition double_condition = 4423 const Condition double_condition =
4424 is_min ? TokenKindToDoubleCondition(Token::kLT) 4424 is_min ? TokenKindToDoubleCondition(Token::kLT)
4425 : TokenKindToDoubleCondition(Token::kGT); 4425 : TokenKindToDoubleCondition(Token::kGT);
4426 ASSERT(left == result); 4426 ASSERT(left == result);
4427 __ j(double_condition, &done, Assembler::kNearJump); 4427 __ j(double_condition, &done, Assembler::kNearJump);
4428 __ movsd(result, right); 4428 __ movsd(result, right);
(...skipping 23 matching lines...) Expand all
4452 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left. 4452 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left.
4453 } 4453 }
4454 __ movsd(result, right); 4454 __ movsd(result, right);
4455 __ Bind(&done); 4455 __ Bind(&done);
4456 return; 4456 return;
4457 } 4457 }
4458 4458
4459 ASSERT(result_cid() == kSmiCid); 4459 ASSERT(result_cid() == kSmiCid);
4460 Register left = locs()->in(0).reg(); 4460 Register left = locs()->in(0).reg();
4461 Register right = locs()->in(1).reg(); 4461 Register right = locs()->in(1).reg();
4462 Register result = locs()->out().reg(); 4462 Register result = locs()->out(0).reg();
4463 __ cmpq(left, right); 4463 __ cmpq(left, right);
4464 ASSERT(result == left); 4464 ASSERT(result == left);
4465 if (is_min) { 4465 if (is_min) {
4466 __ cmovgeq(result, right); 4466 __ cmovgeq(result, right);
4467 } else { 4467 } else {
4468 __ cmovlessq(result, right); 4468 __ cmovlessq(result, right);
4469 } 4469 }
4470 } 4470 }
4471 4471
4472 4472
4473 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { 4473 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const {
4474 const intptr_t kNumInputs = 1; 4474 const intptr_t kNumInputs = 1;
4475 const intptr_t kNumTemps = 0; 4475 const intptr_t kNumTemps = 0;
4476 LocationSummary* result = 4476 LocationSummary* result =
4477 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4477 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4478 result->set_in(0, Location::WritableRegister()); 4478 result->set_in(0, Location::WritableRegister());
4479 result->set_out(Location::RequiresFpuRegister()); 4479 result->set_out(0, Location::RequiresFpuRegister());
4480 return result; 4480 return result;
4481 } 4481 }
4482 4482
4483 4483
4484 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4484 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4485 Register value = locs()->in(0).reg(); 4485 Register value = locs()->in(0).reg();
4486 FpuRegister result = locs()->out().fpu_reg(); 4486 FpuRegister result = locs()->out(0).fpu_reg();
4487 __ SmiUntag(value); 4487 __ SmiUntag(value);
4488 __ cvtsi2sd(result, value); 4488 __ cvtsi2sd(result, value);
4489 } 4489 }
4490 4490
4491 4491
4492 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { 4492 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const {
4493 const intptr_t kNumInputs = 1; 4493 const intptr_t kNumInputs = 1;
4494 const intptr_t kNumTemps = 1; 4494 const intptr_t kNumTemps = 1;
4495 LocationSummary* result = 4495 LocationSummary* result =
4496 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4496 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4497 result->set_in(0, Location::RegisterLocation(RCX)); 4497 result->set_in(0, Location::RegisterLocation(RCX));
4498 result->set_out(Location::RegisterLocation(RAX)); 4498 result->set_out(0, Location::RegisterLocation(RAX));
4499 result->set_temp(0, Location::RegisterLocation(RBX)); 4499 result->set_temp(0, Location::RegisterLocation(RBX));
4500 return result; 4500 return result;
4501 } 4501 }
4502 4502
4503 4503
4504 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4504 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4505 Register result = locs()->out().reg(); 4505 Register result = locs()->out(0).reg();
4506 Register value_obj = locs()->in(0).reg(); 4506 Register value_obj = locs()->in(0).reg();
4507 Register temp = locs()->temp(0).reg(); 4507 Register temp = locs()->temp(0).reg();
4508 XmmRegister value_double = XMM0; 4508 XmmRegister value_double = XMM0;
4509 ASSERT(result == RAX); 4509 ASSERT(result == RAX);
4510 ASSERT(result != value_obj); 4510 ASSERT(result != value_obj);
4511 ASSERT(result != temp); 4511 ASSERT(result != temp);
4512 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset())); 4512 __ movsd(value_double, FieldAddress(value_obj, Double::value_offset()));
4513 __ cvttsd2siq(result, value_double); 4513 __ cvttsd2siq(result, value_double);
4514 // Overflow is signalled with minint. 4514 // Overflow is signalled with minint.
4515 Label do_call, done; 4515 Label do_call, done;
(...skipping 23 matching lines...) Expand all
4539 __ Bind(&done); 4539 __ Bind(&done);
4540 } 4540 }
4541 4541
4542 4542
4543 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { 4543 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const {
4544 const intptr_t kNumInputs = 1; 4544 const intptr_t kNumInputs = 1;
4545 const intptr_t kNumTemps = 1; 4545 const intptr_t kNumTemps = 1;
4546 LocationSummary* result = new LocationSummary( 4546 LocationSummary* result = new LocationSummary(
4547 kNumInputs, kNumTemps, LocationSummary::kNoCall); 4547 kNumInputs, kNumTemps, LocationSummary::kNoCall);
4548 result->set_in(0, Location::RequiresFpuRegister()); 4548 result->set_in(0, Location::RequiresFpuRegister());
4549 result->set_out(Location:: Location::RequiresRegister()); 4549 result->set_out(0, Location:: Location::RequiresRegister());
4550 result->set_temp(0, Location::RequiresRegister()); 4550 result->set_temp(0, Location::RequiresRegister());
4551 return result; 4551 return result;
4552 } 4552 }
4553 4553
4554 4554
4555 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4555 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4556 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 4556 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
4557 Register result = locs()->out().reg(); 4557 Register result = locs()->out(0).reg();
4558 XmmRegister value = locs()->in(0).fpu_reg(); 4558 XmmRegister value = locs()->in(0).fpu_reg();
4559 Register temp = locs()->temp(0).reg(); 4559 Register temp = locs()->temp(0).reg();
4560 4560
4561 __ cvttsd2siq(result, value); 4561 __ cvttsd2siq(result, value);
4562 // Overflow is signalled with minint. 4562 // Overflow is signalled with minint.
4563 Label do_call, done; 4563 Label do_call, done;
4564 // Check for overflow and that it fits into Smi. 4564 // Check for overflow and that it fits into Smi.
4565 __ movq(temp, result); 4565 __ movq(temp, result);
4566 __ shlq(temp, Immediate(1)); 4566 __ shlq(temp, Immediate(1));
4567 __ j(OVERFLOW, deopt); 4567 __ j(OVERFLOW, deopt);
4568 __ SmiTag(result); 4568 __ SmiTag(result);
4569 if (FLAG_throw_on_javascript_int_overflow) { 4569 if (FLAG_throw_on_javascript_int_overflow) {
4570 EmitJavascriptOverflowCheck(compiler, range(), deopt, result); 4570 EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
4571 } 4571 }
4572 } 4572 }
4573 4573
4574 4574
4575 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { 4575 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const {
4576 const intptr_t kNumInputs = 1; 4576 const intptr_t kNumInputs = 1;
4577 const intptr_t kNumTemps = 0; 4577 const intptr_t kNumTemps = 0;
4578 LocationSummary* result = 4578 LocationSummary* result =
4579 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4579 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4580 result->set_in(0, Location::RequiresFpuRegister()); 4580 result->set_in(0, Location::RequiresFpuRegister());
4581 result->set_out(Location::RequiresFpuRegister()); 4581 result->set_out(0, Location::RequiresFpuRegister());
4582 return result; 4582 return result;
4583 } 4583 }
4584 4584
4585 4585
4586 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4586 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4587 XmmRegister value = locs()->in(0).fpu_reg(); 4587 XmmRegister value = locs()->in(0).fpu_reg();
4588 XmmRegister result = locs()->out().fpu_reg(); 4588 XmmRegister result = locs()->out(0).fpu_reg();
4589 switch (recognized_kind()) { 4589 switch (recognized_kind()) {
4590 case MethodRecognizer::kDoubleTruncate: 4590 case MethodRecognizer::kDoubleTruncate:
4591 __ roundsd(result, value, Assembler::kRoundToZero); 4591 __ roundsd(result, value, Assembler::kRoundToZero);
4592 break; 4592 break;
4593 case MethodRecognizer::kDoubleFloor: 4593 case MethodRecognizer::kDoubleFloor:
4594 __ roundsd(result, value, Assembler::kRoundDown); 4594 __ roundsd(result, value, Assembler::kRoundDown);
4595 break; 4595 break;
4596 case MethodRecognizer::kDoubleCeil: 4596 case MethodRecognizer::kDoubleCeil:
4597 __ roundsd(result, value, Assembler::kRoundUp); 4597 __ roundsd(result, value, Assembler::kRoundUp);
4598 break; 4598 break;
4599 default: 4599 default:
4600 UNREACHABLE(); 4600 UNREACHABLE();
4601 } 4601 }
4602 } 4602 }
4603 4603
4604 4604
4605 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { 4605 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
4606 const intptr_t kNumInputs = 1; 4606 const intptr_t kNumInputs = 1;
4607 const intptr_t kNumTemps = 0; 4607 const intptr_t kNumTemps = 0;
4608 LocationSummary* result = 4608 LocationSummary* result =
4609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4609 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4610 result->set_in(0, Location::RequiresFpuRegister()); 4610 result->set_in(0, Location::RequiresFpuRegister());
4611 result->set_out(Location::SameAsFirstInput()); 4611 result->set_out(0, Location::SameAsFirstInput());
4612 return result; 4612 return result;
4613 } 4613 }
4614 4614
4615 4615
4616 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4616 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4617 __ cvtsd2ss(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4617 __ cvtsd2ss(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4618 } 4618 }
4619 4619
4620 4620
4621 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { 4621 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
4622 const intptr_t kNumInputs = 1; 4622 const intptr_t kNumInputs = 1;
4623 const intptr_t kNumTemps = 0; 4623 const intptr_t kNumTemps = 0;
4624 LocationSummary* result = 4624 LocationSummary* result =
4625 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4625 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4626 result->set_in(0, Location::RequiresFpuRegister()); 4626 result->set_in(0, Location::RequiresFpuRegister());
4627 result->set_out(Location::SameAsFirstInput()); 4627 result->set_out(0, Location::SameAsFirstInput());
4628 return result; 4628 return result;
4629 } 4629 }
4630 4630
4631 4631
4632 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4632 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4633 __ cvtss2sd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4633 __ cvtss2sd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
4634 } 4634 }
4635 4635
4636 4636
4637 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 4637 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
4638 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 4638 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
4639 // double arguments and XMM0 to return the result. Unfortunately 4639 // double arguments and XMM0 to return the result. Unfortunately
4640 // currently we can't specify these registers because ParallelMoveResolver 4640 // currently we can't specify these registers because ParallelMoveResolver
4641 // assumes that XMM0 is free at all times. 4641 // assumes that XMM0 is free at all times.
4642 // TODO(vegorov): allow XMM0 to be used. 4642 // TODO(vegorov): allow XMM0 to be used.
4643 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4643 ASSERT((InputCount() == 1) || (InputCount() == 2));
4644 const intptr_t kNumTemps = 1; 4644 const intptr_t kNumTemps = 1;
4645 LocationSummary* result = 4645 LocationSummary* result =
4646 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4646 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
4647 result->set_temp(0, Location::RegisterLocation(R13)); 4647 result->set_temp(0, Location::RegisterLocation(R13));
4648 result->set_in(0, Location::FpuRegisterLocation(XMM2)); 4648 result->set_in(0, Location::FpuRegisterLocation(XMM2));
4649 if (InputCount() == 2) { 4649 if (InputCount() == 2) {
4650 result->set_in(1, Location::FpuRegisterLocation(XMM1)); 4650 result->set_in(1, Location::FpuRegisterLocation(XMM1));
4651 } 4651 }
4652 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4652 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4653 // Temp index 1. 4653 // Temp index 1.
4654 result->AddTemp(Location::RegisterLocation(RAX)); 4654 result->AddTemp(Location::RegisterLocation(RAX));
4655 // Temp index 2. 4655 // Temp index 2.
4656 result->AddTemp(Location::FpuRegisterLocation(XMM4)); 4656 result->AddTemp(Location::FpuRegisterLocation(XMM4));
4657 } 4657 }
4658 result->set_out(Location::FpuRegisterLocation(XMM3)); 4658 result->set_out(0, Location::FpuRegisterLocation(XMM3));
4659 return result; 4659 return result;
4660 } 4660 }
4661 4661
4662 4662
4663 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4663 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4664 // Save RSP. 4664 // Save RSP.
4665 __ movq(locs()->temp(kSavedSpTempIndex).reg(), RSP); 4665 __ movq(locs()->temp(kSavedSpTempIndex).reg(), RSP);
4666 __ ReserveAlignedFrameSpace(0); 4666 __ ReserveAlignedFrameSpace(0);
4667 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4667 __ movaps(XMM0, locs()->in(0).fpu_reg());
4668 if (InputCount() == 2) { 4668 if (InputCount() == 2) {
4669 ASSERT(locs()->in(1).fpu_reg() == XMM1); 4669 ASSERT(locs()->in(1).fpu_reg() == XMM1);
4670 } 4670 }
4671 // For pow-function return NaN if exponent is NaN. 4671 // For pow-function return NaN if exponent is NaN.
4672 Label do_call, skip_call; 4672 Label do_call, skip_call;
4673 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4673 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4674 // Pseudo code: 4674 // Pseudo code:
4675 // if (exponent == 0.0) return 0.0; 4675 // if (exponent == 0.0) return 0.0;
4676 // if (base == 1.0) return 1.0; 4676 // if (base == 1.0) return 1.0;
4677 // if (base.isNaN || exponent.isNaN) { 4677 // if (base.isNaN || exponent.isNaN) {
4678 // return double.NAN; 4678 // return double.NAN;
4679 // } 4679 // }
4680 XmmRegister base = locs()->in(0).fpu_reg(); 4680 XmmRegister base = locs()->in(0).fpu_reg();
4681 XmmRegister exp = locs()->in(1).fpu_reg(); 4681 XmmRegister exp = locs()->in(1).fpu_reg();
4682 XmmRegister result = locs()->out().fpu_reg(); 4682 XmmRegister result = locs()->out(0).fpu_reg();
4683 Register temp = locs()->temp(kObjectTempIndex).reg(); 4683 Register temp = locs()->temp(kObjectTempIndex).reg();
4684 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg(); 4684 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg();
4685 4685
4686 // Check if exponent is 0.0 -> return 1.0; 4686 // Check if exponent is 0.0 -> return 1.0;
4687 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP); 4687 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP);
4688 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); 4688 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
4689 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP); 4689 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP);
4690 __ movsd(result, FieldAddress(temp, Double::value_offset())); 4690 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4691 // 'result' contains 1.0. 4691 // 'result' contains 1.0.
4692 Label exp_is_nan; 4692 Label exp_is_nan;
(...skipping 16 matching lines...) Expand all
4709 __ Bind(&exp_is_nan); 4709 __ Bind(&exp_is_nan);
4710 // Checks if base == 1.0. 4710 // Checks if base == 1.0.
4711 __ comisd(base, result); 4711 __ comisd(base, result);
4712 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); 4712 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
4713 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 4713 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0
4714 __ movsd(result, exp); // result is NaN 4714 __ movsd(result, exp); // result is NaN
4715 __ jmp(&skip_call, Assembler::kNearJump); 4715 __ jmp(&skip_call, Assembler::kNearJump);
4716 } 4716 }
4717 __ Bind(&do_call); 4717 __ Bind(&do_call);
4718 __ CallRuntime(TargetFunction(), InputCount()); 4718 __ CallRuntime(TargetFunction(), InputCount());
4719 __ movaps(locs()->out().fpu_reg(), XMM0); 4719 __ movaps(locs()->out(0).fpu_reg(), XMM0);
4720 __ Bind(&skip_call); 4720 __ Bind(&skip_call);
4721 // Restore RSP. 4721 // Restore RSP.
4722 __ movq(RSP, locs()->temp(kSavedSpTempIndex).reg()); 4722 __ movq(RSP, locs()->temp(kSavedSpTempIndex).reg());
4723 } 4723 }
4724 4724
4725 4725
4726 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4726 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4727 if (kind() == MergedMathInstr::kTruncDivMod) { 4727 if (kind() == MergedMathInstr::kTruncDivMod) {
4728 const intptr_t kNumInputs = 2; 4728 const intptr_t kNumInputs = 2;
4729 const intptr_t kNumTemps = 1; 4729 const intptr_t kNumTemps = 1;
4730 LocationSummary* summary = 4730 LocationSummary* summary =
4731 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4731 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4732 // Both inputs must be writable because they will be untagged. 4732 // Both inputs must be writable because they will be untagged.
4733 summary->set_in(0, Location::RegisterLocation(RAX)); 4733 summary->set_in(0, Location::RegisterLocation(RAX));
4734 summary->set_in(1, Location::WritableRegister()); 4734 summary->set_in(1, Location::WritableRegister());
4735 summary->set_out(Location::RequiresRegister()); 4735 summary->set_out(0, Location::RequiresRegister());
4736 // Will be used for sign extension and division. 4736 // Will be used for sign extension and division.
4737 summary->set_temp(0, Location::RegisterLocation(RDX)); 4737 summary->set_temp(0, Location::RegisterLocation(RDX));
4738 return summary; 4738 return summary;
4739 } 4739 }
4740 if (kind() == MergedMathInstr::kSinCos) { 4740 if (kind() == MergedMathInstr::kSinCos) {
4741 const intptr_t kNumInputs = 1; 4741 const intptr_t kNumInputs = 1;
4742 const intptr_t kNumTemps = 1; 4742 const intptr_t kNumTemps = 1;
4743 LocationSummary* summary = 4743 LocationSummary* summary =
4744 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4744 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4745 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4745 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4746 // R13 is chosen because it is callee saved so we do not need to back it 4746 // R13 is chosen because it is callee saved so we do not need to back it
4747 // up before calling into the runtime. 4747 // up before calling into the runtime.
4748 summary->set_temp(0, Location::RegisterLocation(R13)); 4748 summary->set_temp(0, Location::RegisterLocation(R13));
4749 summary->set_out(Location::RegisterLocation(RAX)); 4749 summary->set_out(0, Location::RegisterLocation(RAX));
4750 return summary; 4750 return summary;
4751 } 4751 }
4752 UNIMPLEMENTED(); 4752 UNIMPLEMENTED();
4753 return NULL; 4753 return NULL;
4754 } 4754 }
4755 4755
4756 4756
4757 4757
4758 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4758 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
4759 4759
4760 extern const RuntimeEntry kSinCosRuntimeEntry( 4760 extern const RuntimeEntry kSinCosRuntimeEntry(
4761 "libc_sincos", reinterpret_cast<RuntimeFunction>( 4761 "libc_sincos", reinterpret_cast<RuntimeFunction>(
4762 static_cast<SinCosCFunction>(&SinCos)), 1, true, true); 4762 static_cast<SinCosCFunction>(&SinCos)), 1, true, true);
4763 4763
4764 4764
4765 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4765 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4766 Label* deopt = NULL; 4766 Label* deopt = NULL;
4767 if (CanDeoptimize()) { 4767 if (CanDeoptimize()) {
4768 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4768 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4769 } 4769 }
4770 if (kind() == MergedMathInstr::kTruncDivMod) { 4770 if (kind() == MergedMathInstr::kTruncDivMod) {
4771 Register left = locs()->in(0).reg(); 4771 Register left = locs()->in(0).reg();
4772 Register right = locs()->in(1).reg(); 4772 Register right = locs()->in(1).reg();
4773 Register result = locs()->out().reg(); 4773 Register result = locs()->out(0).reg();
4774 Label not_32bit, done; 4774 Label not_32bit, done;
4775 Register temp = locs()->temp(0).reg(); 4775 Register temp = locs()->temp(0).reg();
4776 ASSERT(left == RAX); 4776 ASSERT(left == RAX);
4777 ASSERT((right != RDX) && (right != RAX)); 4777 ASSERT((right != RDX) && (right != RAX));
4778 ASSERT(temp == RDX); 4778 ASSERT(temp == RDX);
4779 ASSERT((result != RDX) && (result != RAX)); 4779 ASSERT((result != RDX) && (result != RAX));
4780 4780
4781 Range* right_range = InputAt(1)->definition()->range(); 4781 Range* right_range = InputAt(1)->definition()->range();
4782 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4782 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4783 // Handle divide by zero in runtime. 4783 // Handle divide by zero in runtime.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4888 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize)); 4888 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize));
4889 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize)); 4889 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize));
4890 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4890 __ movaps(XMM0, locs()->in(0).fpu_reg());
4891 4891
4892 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); 4892 __ CallRuntime(kSinCosRuntimeEntry, InputCount());
4893 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. 4893 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin.
4894 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. 4894 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos.
4895 // Restore RSP. 4895 // Restore RSP.
4896 __ movq(RSP, locs()->temp(0).reg()); 4896 __ movq(RSP, locs()->temp(0).reg());
4897 4897
4898 Register result = locs()->out().reg(); 4898 Register result = locs()->out(0).reg();
4899 const TypedData& res_array = TypedData::ZoneHandle( 4899 const TypedData& res_array = TypedData::ZoneHandle(
4900 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld)); 4900 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld));
4901 __ LoadObject(result, res_array, PP); 4901 __ LoadObject(result, res_array, PP);
4902 const intptr_t index_scale = 4902 const intptr_t index_scale =
4903 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid); 4903 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid);
4904 Address sin_address( 4904 Address sin_address(
4905 FlowGraphCompiler::ElementAddressForIntIndex( 4905 FlowGraphCompiler::ElementAddressForIntIndex(
4906 kTypedDataFloat64ArrayCid, index_scale, result, 4906 kTypedDataFloat64ArrayCid, index_scale, result,
4907 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin))); 4907 MergedMathInstr::ResultIndexOf(MethodRecognizer::kMathSin)));
4908 Address cos_address( 4908 Address cos_address(
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4955 deopt, 4955 deopt,
4956 deopt_id(), 4956 deopt_id(),
4957 instance_call()->token_pos(), 4957 instance_call()->token_pos(),
4958 locs()); 4958 locs());
4959 } 4959 }
4960 4960
4961 4961
4962 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { 4962 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
4963 comparison()->InitializeLocationSummary(opt); 4963 comparison()->InitializeLocationSummary(opt);
4964 // Branches don't produce a result. 4964 // Branches don't produce a result.
4965 comparison()->locs()->set_out(Location::NoLocation()); 4965 comparison()->locs()->set_out(0, Location::NoLocation());
4966 return comparison()->locs(); 4966 return comparison()->locs();
4967 } 4967 }
4968 4968
4969 4969
4970 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4970 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4971 comparison()->EmitBranchCode(compiler, this); 4971 comparison()->EmitBranchCode(compiler, this);
4972 } 4972 }
4973 4973
4974 4974
4975 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { 4975 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
5245 5245
5246 5246
5247 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { 5247 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
5248 return LocationSummary::Make(0, 5248 return LocationSummary::Make(0,
5249 Location::RequiresRegister(), 5249 Location::RequiresRegister(),
5250 LocationSummary::kNoCall); 5250 LocationSummary::kNoCall);
5251 } 5251 }
5252 5252
5253 5253
5254 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5254 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5255 __ MoveRegister(locs()->out().reg(), CTX); 5255 __ MoveRegister(locs()->out(0).reg(), CTX);
5256 } 5256 }
5257 5257
5258 5258
5259 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { 5259 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
5260 const intptr_t kNumInputs = 2; 5260 const intptr_t kNumInputs = 2;
5261 const intptr_t kNumTemps = 0; 5261 const intptr_t kNumTemps = 0;
5262 if (needs_number_check()) { 5262 if (needs_number_check()) {
5263 LocationSummary* locs = 5263 LocationSummary* locs =
5264 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 5264 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
5265 locs->set_in(0, Location::RegisterLocation(RAX)); 5265 locs->set_in(0, Location::RegisterLocation(RAX));
5266 locs->set_in(1, Location::RegisterLocation(RCX)); 5266 locs->set_in(1, Location::RegisterLocation(RCX));
5267 locs->set_out(Location::RegisterLocation(RAX)); 5267 locs->set_out(0, Location::RegisterLocation(RAX));
5268 return locs; 5268 return locs;
5269 } 5269 }
5270 LocationSummary* locs = 5270 LocationSummary* locs =
5271 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5271 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5272 locs->set_in(0, Location::RegisterOrConstant(left())); 5272 locs->set_in(0, Location::RegisterOrConstant(left()));
5273 // Only one of the inputs can be a constant. Choose register if the first one 5273 // Only one of the inputs can be a constant. Choose register if the first one
5274 // is a constant. 5274 // is a constant.
5275 locs->set_in(1, locs->in(0).IsConstant() 5275 locs->set_in(1, locs->in(0).IsConstant()
5276 ? Location::RequiresRegister() 5276 ? Location::RequiresRegister()
5277 : Location::RegisterOrConstant(right())); 5277 : Location::RegisterOrConstant(right()));
5278 locs->set_out(Location::RequiresRegister()); 5278 locs->set_out(0, Location::RequiresRegister());
5279 return locs; 5279 return locs;
5280 } 5280 }
5281 5281
5282 5282
5283 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 5283 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
5284 BranchLabels labels) { 5284 BranchLabels labels) {
5285 Location left = locs()->in(0); 5285 Location left = locs()->in(0);
5286 Location right = locs()->in(1); 5286 Location right = locs()->in(1);
5287 ASSERT(!left.IsConstant() || !right.IsConstant()); 5287 ASSERT(!left.IsConstant() || !right.IsConstant());
5288 if (left.IsConstant()) { 5288 if (left.IsConstant()) {
(...skipping 20 matching lines...) Expand all
5309 5309
5310 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5310 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5311 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5311 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5312 5312
5313 Label is_true, is_false; 5313 Label is_true, is_false;
5314 BranchLabels labels = { &is_true, &is_false, &is_false }; 5314 BranchLabels labels = { &is_true, &is_false, &is_false };
5315 5315
5316 Condition true_condition = EmitComparisonCode(compiler, labels); 5316 Condition true_condition = EmitComparisonCode(compiler, labels);
5317 EmitBranchOnCondition(compiler, true_condition, labels); 5317 EmitBranchOnCondition(compiler, true_condition, labels);
5318 5318
5319 Register result = locs()->out().reg(); 5319 Register result = locs()->out(0).reg();
5320 Label done; 5320 Label done;
5321 __ Bind(&is_false); 5321 __ Bind(&is_false);
5322 __ LoadObject(result, Bool::False(), PP); 5322 __ LoadObject(result, Bool::False(), PP);
5323 __ jmp(&done); 5323 __ jmp(&done);
5324 __ Bind(&is_true); 5324 __ Bind(&is_true);
5325 __ LoadObject(result, Bool::True(), PP); 5325 __ LoadObject(result, Bool::True(), PP);
5326 __ Bind(&done); 5326 __ Bind(&done);
5327 } 5327 }
5328 5328
5329 5329
5330 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 5330 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
5331 BranchInstr* branch) { 5331 BranchInstr* branch) {
5332 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5332 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5333 5333
5334 BranchLabels labels = compiler->CreateBranchLabels(branch); 5334 BranchLabels labels = compiler->CreateBranchLabels(branch);
5335 Condition true_condition = EmitComparisonCode(compiler, labels); 5335 Condition true_condition = EmitComparisonCode(compiler, labels);
5336 EmitBranchOnCondition(compiler, true_condition, labels); 5336 EmitBranchOnCondition(compiler, true_condition, labels);
5337 } 5337 }
5338 5338
5339 5339
5340 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { 5340 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const {
5341 const intptr_t kNumInputs = 0; 5341 const intptr_t kNumInputs = 0;
5342 const intptr_t kNumTemps = 1; 5342 const intptr_t kNumTemps = 1;
5343 LocationSummary* result = 5343 LocationSummary* result =
5344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 5344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
5345 result->set_out(Location::RegisterLocation(RAX)); 5345 result->set_out(0, Location::RegisterLocation(RAX));
5346 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 5346 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
5347 return result; 5347 return result;
5348 } 5348 }
5349 5349
5350 5350
5351 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5351 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5352 // The arguments to the stub include the closure, as does the arguments 5352 // The arguments to the stub include the closure, as does the arguments
5353 // descriptor. 5353 // descriptor.
5354 Register temp_reg = locs()->temp(0).reg(); 5354 Register temp_reg = locs()->temp(0).reg();
5355 int argument_count = ArgumentCount(); 5355 int argument_count = ArgumentCount();
(...skipping 13 matching lines...) Expand all
5369 5369
5370 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { 5370 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
5371 return LocationSummary::Make(1, 5371 return LocationSummary::Make(1,
5372 Location::RequiresRegister(), 5372 Location::RequiresRegister(),
5373 LocationSummary::kNoCall); 5373 LocationSummary::kNoCall);
5374 } 5374 }
5375 5375
5376 5376
5377 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5377 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5378 Register value = locs()->in(0).reg(); 5378 Register value = locs()->in(0).reg();
5379 Register result = locs()->out().reg(); 5379 Register result = locs()->out(0).reg();
5380 5380
5381 Label done; 5381 Label done;
5382 __ LoadObject(result, Bool::True(), PP); 5382 __ LoadObject(result, Bool::True(), PP);
5383 __ CompareRegisters(result, value); 5383 __ CompareRegisters(result, value);
5384 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 5384 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
5385 __ LoadObject(result, Bool::False(), PP); 5385 __ LoadObject(result, Bool::False(), PP);
5386 __ Bind(&done); 5386 __ Bind(&done);
5387 } 5387 }
5388 5388
5389 5389
(...skipping 10 matching lines...) Expand all
5400 PcDescriptors::kOther, 5400 PcDescriptors::kOther,
5401 locs()); 5401 locs());
5402 __ Drop(ArgumentCount()); // Discard arguments. 5402 __ Drop(ArgumentCount()); // Discard arguments.
5403 } 5403 }
5404 5404
5405 } // namespace dart 5405 } // namespace dart
5406 5406
5407 #undef __ 5407 #undef __
5408 5408
5409 #endif // defined TARGET_ARCH_X64 5409 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698