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

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

Issue 207063002: Refactor to support multiple outputs in location summary (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 namespace dart { 22 namespace dart {
23 23
24 DECLARE_FLAG(int, optimization_counter_threshold); 24 DECLARE_FLAG(int, optimization_counter_threshold);
25 DECLARE_FLAG(bool, propagate_ic_data); 25 DECLARE_FLAG(bool, propagate_ic_data);
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 V0. 29 // on the stack and return the result in a fixed register V0.
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(V0)); 32 result->set_out(0, Location::RegisterLocation(V0));
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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 122 }
123 123
124 124
125 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { 125 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const {
126 comparison()->InitializeLocationSummary(opt); 126 comparison()->InitializeLocationSummary(opt);
127 return comparison()->locs(); 127 return comparison()->locs();
128 } 128 }
129 129
130 130
131 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 131 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
132 const Register result = locs()->out().reg(); 132 const Register result = locs()->out(0).reg();
133 133
134 Location left = locs()->in(0); 134 Location left = locs()->in(0);
135 Location right = locs()->in(1); 135 Location right = locs()->in(1);
136 ASSERT(!left.IsConstant() || !right.IsConstant()); 136 ASSERT(!left.IsConstant() || !right.IsConstant());
137 137
138 // Clear out register. 138 // Clear out register.
139 __ mov(result, ZR); 139 __ mov(result, ZR);
140 140
141 // Emit comparison code. This must not overwrite the result register. 141 // Emit comparison code. This must not overwrite the result register.
142 BranchLabels labels = { NULL, NULL, NULL }; 142 BranchLabels labels = { NULL, NULL, NULL };
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 } 202 }
203 } 203 }
204 } 204 }
205 205
206 206
207 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { 207 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const {
208 const intptr_t kNumInputs = 0; 208 const intptr_t kNumInputs = 0;
209 const intptr_t kNumTemps = 1; 209 const intptr_t kNumTemps = 1;
210 LocationSummary* result = 210 LocationSummary* result =
211 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 211 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
212 result->set_out(Location::RegisterLocation(V0)); 212 result->set_out(0, Location::RegisterLocation(V0));
213 result->set_temp(0, Location::RegisterLocation(S4)); // Arg. descriptor. 213 result->set_temp(0, Location::RegisterLocation(S4)); // Arg. descriptor.
214 return result; 214 return result;
215 } 215 }
216 216
217 217
218 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 218 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
219 // The arguments to the stub include the closure, as does the arguments 219 // The arguments to the stub include the closure, as does the arguments
220 // descriptor. 220 // descriptor.
221 Register temp_reg = locs()->temp(0).reg(); 221 Register temp_reg = locs()->temp(0).reg();
222 int argument_count = ArgumentCount(); 222 int argument_count = ArgumentCount();
(...skipping 13 matching lines...) Expand all
236 236
237 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { 237 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
238 return LocationSummary::Make(0, 238 return LocationSummary::Make(0,
239 Location::RequiresRegister(), 239 Location::RequiresRegister(),
240 LocationSummary::kNoCall); 240 LocationSummary::kNoCall);
241 } 241 }
242 242
243 243
244 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 244 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
245 __ TraceSimMsg("LoadLocalInstr"); 245 __ TraceSimMsg("LoadLocalInstr");
246 Register result = locs()->out().reg(); 246 Register result = locs()->out(0).reg();
247 __ lw(result, Address(FP, local().index() * kWordSize)); 247 __ lw(result, Address(FP, local().index() * kWordSize));
248 } 248 }
249 249
250 250
251 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { 251 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
252 return LocationSummary::Make(1, 252 return LocationSummary::Make(1,
253 Location::SameAsFirstInput(), 253 Location::SameAsFirstInput(),
254 LocationSummary::kNoCall); 254 LocationSummary::kNoCall);
255 } 255 }
256 256
257 257
258 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 258 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
259 __ TraceSimMsg("StoreLocalInstr"); 259 __ TraceSimMsg("StoreLocalInstr");
260 Register value = locs()->in(0).reg(); 260 Register value = locs()->in(0).reg();
261 Register result = locs()->out().reg(); 261 Register result = locs()->out(0).reg();
262 ASSERT(result == value); // Assert that register assignment is correct. 262 ASSERT(result == value); // Assert that register assignment is correct.
263 __ sw(value, Address(FP, local().index() * kWordSize)); 263 __ sw(value, Address(FP, local().index() * kWordSize));
264 } 264 }
265 265
266 266
267 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { 267 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
268 return LocationSummary::Make(0, 268 return LocationSummary::Make(0,
269 Location::RequiresRegister(), 269 Location::RequiresRegister(),
270 LocationSummary::kNoCall); 270 LocationSummary::kNoCall);
271 } 271 }
272 272
273 273
274 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 274 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
275 // The register allocator drops constant definitions that have no uses. 275 // The register allocator drops constant definitions that have no uses.
276 if (!locs()->out().IsInvalid()) { 276 if (!locs()->out(0).IsInvalid()) {
277 __ TraceSimMsg("ConstantInstr"); 277 __ TraceSimMsg("ConstantInstr");
278 Register result = locs()->out().reg(); 278 Register result = locs()->out(0).reg();
279 __ LoadObject(result, value()); 279 __ LoadObject(result, value());
280 } 280 }
281 } 281 }
282 282
283 283
284 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { 284 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
285 const intptr_t kNumInputs = 3; 285 const intptr_t kNumInputs = 3;
286 const intptr_t kNumTemps = 0; 286 const intptr_t kNumTemps = 0;
287 LocationSummary* summary = 287 LocationSummary* summary =
288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
289 summary->set_in(0, Location::RegisterLocation(A0)); // Value. 289 summary->set_in(0, Location::RegisterLocation(A0)); // Value.
290 summary->set_in(1, Location::RegisterLocation(A2)); // Instantiator. 290 summary->set_in(1, Location::RegisterLocation(A2)); // Instantiator.
291 summary->set_in(2, Location::RegisterLocation(A1)); // Type arguments. 291 summary->set_in(2, Location::RegisterLocation(A1)); // Type arguments.
292 summary->set_out(Location::RegisterLocation(A0)); 292 summary->set_out(0, Location::RegisterLocation(A0));
293 return summary; 293 return summary;
294 } 294 }
295 295
296 296
297 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { 297 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const {
298 const intptr_t kNumInputs = 1; 298 const intptr_t kNumInputs = 1;
299 const intptr_t kNumTemps = 0; 299 const intptr_t kNumTemps = 0;
300 LocationSummary* locs = 300 LocationSummary* locs =
301 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 301 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
302 locs->set_in(0, Location::RegisterLocation(A0)); 302 locs->set_in(0, Location::RegisterLocation(A0));
303 locs->set_out(Location::RegisterLocation(A0)); 303 locs->set_out(0, Location::RegisterLocation(A0));
304 return locs; 304 return locs;
305 } 305 }
306 306
307 307
308 static void EmitAssertBoolean(Register reg, 308 static void EmitAssertBoolean(Register reg,
309 intptr_t token_pos, 309 intptr_t token_pos,
310 intptr_t deopt_id, 310 intptr_t deopt_id,
311 LocationSummary* locs, 311 LocationSummary* locs,
312 FlowGraphCompiler* compiler) { 312 FlowGraphCompiler* compiler) {
313 // Check that the type of the value is allowed in conditional context. 313 // Check that the type of the value is allowed in conditional context.
(...skipping 10 matching lines...) Expand all
324 1, 324 1,
325 locs); 325 locs);
326 // We should never return here. 326 // We should never return here.
327 __ break_(0); 327 __ break_(0);
328 __ Bind(&done); 328 __ Bind(&done);
329 } 329 }
330 330
331 331
332 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 332 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
333 Register obj = locs()->in(0).reg(); 333 Register obj = locs()->in(0).reg();
334 Register result = locs()->out().reg(); 334 Register result = locs()->out(0).reg();
335 335
336 __ TraceSimMsg("AssertBooleanInstr"); 336 __ TraceSimMsg("AssertBooleanInstr");
337 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 337 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
338 ASSERT(obj == result); 338 ASSERT(obj == result);
339 } 339 }
340 340
341 341
342 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { 342 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const {
343 const intptr_t kNumInputs = 2; 343 const intptr_t kNumInputs = 2;
344 if (operation_cid() == kMintCid) { 344 if (operation_cid() == kMintCid) {
345 const intptr_t kNumTemps = 1; 345 const intptr_t kNumTemps = 1;
346 LocationSummary* locs = 346 LocationSummary* locs =
347 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 347 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
348 locs->set_in(0, Location::RequiresFpuRegister()); 348 locs->set_in(0, Location::RequiresFpuRegister());
349 locs->set_in(1, Location::RequiresFpuRegister()); 349 locs->set_in(1, Location::RequiresFpuRegister());
350 locs->set_temp(0, Location::RequiresRegister()); 350 locs->set_temp(0, Location::RequiresRegister());
351 locs->set_out(Location::RequiresRegister()); 351 locs->set_out(0, Location::RequiresRegister());
352 return locs; 352 return locs;
353 } 353 }
354 if (operation_cid() == kDoubleCid) { 354 if (operation_cid() == kDoubleCid) {
355 const intptr_t kNumTemps = 0; 355 const intptr_t kNumTemps = 0;
356 LocationSummary* locs = 356 LocationSummary* locs =
357 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 357 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
358 locs->set_in(0, Location::RequiresFpuRegister()); 358 locs->set_in(0, Location::RequiresFpuRegister());
359 locs->set_in(1, Location::RequiresFpuRegister()); 359 locs->set_in(1, Location::RequiresFpuRegister());
360 locs->set_out(Location::RequiresRegister()); 360 locs->set_out(0, Location::RequiresRegister());
361 return locs; 361 return locs;
362 } 362 }
363 if (operation_cid() == kSmiCid) { 363 if (operation_cid() == kSmiCid) {
364 const intptr_t kNumTemps = 0; 364 const intptr_t kNumTemps = 0;
365 LocationSummary* locs = 365 LocationSummary* locs =
366 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 366 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
367 locs->set_in(0, Location::RegisterOrConstant(left())); 367 locs->set_in(0, Location::RegisterOrConstant(left()));
368 // Only one input can be a constant operand. The case of two constant 368 // Only one input can be a constant operand. The case of two constant
369 // operands should be handled by constant propagation. 369 // operands should be handled by constant propagation.
370 locs->set_in(1, locs->in(0).IsConstant() 370 locs->set_in(1, locs->in(0).IsConstant()
371 ? Location::RequiresRegister() 371 ? Location::RequiresRegister()
372 : Location::RegisterOrConstant(right())); 372 : Location::RegisterOrConstant(right()));
373 locs->set_out(Location::RequiresRegister()); 373 locs->set_out(0, Location::RequiresRegister());
374 return locs; 374 return locs;
375 } 375 }
376 UNREACHABLE(); 376 UNREACHABLE();
377 return NULL; 377 return NULL;
378 } 378 }
379 379
380 380
381 static void LoadValueCid(FlowGraphCompiler* compiler, 381 static void LoadValueCid(FlowGraphCompiler* compiler,
382 Register value_cid_reg, 382 Register value_cid_reg,
383 Register value_reg, 383 Register value_reg,
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 561
562 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 562 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
563 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 563 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
564 __ Comment("EqualityCompareInstr"); 564 __ Comment("EqualityCompareInstr");
565 565
566 Label is_true, is_false; 566 Label is_true, is_false;
567 BranchLabels labels = { &is_true, &is_false, &is_false }; 567 BranchLabels labels = { &is_true, &is_false, &is_false };
568 Condition true_condition = EmitComparisonCode(compiler, labels); 568 Condition true_condition = EmitComparisonCode(compiler, labels);
569 EmitBranchOnCondition(compiler, true_condition, labels); 569 EmitBranchOnCondition(compiler, true_condition, labels);
570 570
571 Register result = locs()->out().reg(); 571 Register result = locs()->out(0).reg();
572 Label done; 572 Label done;
573 __ Bind(&is_false); 573 __ Bind(&is_false);
574 __ LoadObject(result, Bool::False()); 574 __ LoadObject(result, Bool::False());
575 __ b(&done); 575 __ b(&done);
576 __ Bind(&is_true); 576 __ Bind(&is_true);
577 __ LoadObject(result, Bool::True()); 577 __ LoadObject(result, Bool::True());
578 __ Bind(&done); 578 __ Bind(&done);
579 } 579 }
580 580
581 581
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 const intptr_t kNumInputs = 2; 640 const intptr_t kNumInputs = 2;
641 const intptr_t kNumTemps = 0; 641 const intptr_t kNumTemps = 0;
642 if (operation_cid() == kMintCid) { 642 if (operation_cid() == kMintCid) {
643 const intptr_t kNumTemps = 2; 643 const intptr_t kNumTemps = 2;
644 LocationSummary* locs = 644 LocationSummary* locs =
645 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 645 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
646 locs->set_in(0, Location::RequiresFpuRegister()); 646 locs->set_in(0, Location::RequiresFpuRegister());
647 locs->set_in(1, Location::RequiresFpuRegister()); 647 locs->set_in(1, Location::RequiresFpuRegister());
648 locs->set_temp(0, Location::RequiresRegister()); 648 locs->set_temp(0, Location::RequiresRegister());
649 locs->set_temp(1, Location::RequiresRegister()); 649 locs->set_temp(1, Location::RequiresRegister());
650 locs->set_out(Location::RequiresRegister()); 650 locs->set_out(0, Location::RequiresRegister());
651 return locs; 651 return locs;
652 } 652 }
653 if (operation_cid() == kDoubleCid) { 653 if (operation_cid() == kDoubleCid) {
654 LocationSummary* summary = 654 LocationSummary* summary =
655 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 655 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
656 summary->set_in(0, Location::RequiresFpuRegister()); 656 summary->set_in(0, Location::RequiresFpuRegister());
657 summary->set_in(1, Location::RequiresFpuRegister()); 657 summary->set_in(1, Location::RequiresFpuRegister());
658 summary->set_out(Location::RequiresRegister()); 658 summary->set_out(0, Location::RequiresRegister());
659 return summary; 659 return summary;
660 } 660 }
661 ASSERT(operation_cid() == kSmiCid); 661 ASSERT(operation_cid() == kSmiCid);
662 LocationSummary* summary = 662 LocationSummary* summary =
663 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 663 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
664 summary->set_in(0, Location::RegisterOrConstant(left())); 664 summary->set_in(0, Location::RegisterOrConstant(left()));
665 // Only one input can be a constant operand. The case of two constant 665 // Only one input can be a constant operand. The case of two constant
666 // operands should be handled by constant propagation. 666 // operands should be handled by constant propagation.
667 summary->set_in(1, summary->in(0).IsConstant() 667 summary->set_in(1, summary->in(0).IsConstant()
668 ? Location::RequiresRegister() 668 ? Location::RequiresRegister()
669 : Location::RegisterOrConstant(right())); 669 : Location::RegisterOrConstant(right()));
670 summary->set_out(Location::RequiresRegister()); 670 summary->set_out(0, Location::RequiresRegister());
671 return summary; 671 return summary;
672 } 672 }
673 673
674 674
675 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 675 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
676 BranchLabels labels) { 676 BranchLabels labels) {
677 if (operation_cid() == kSmiCid) { 677 if (operation_cid() == kSmiCid) {
678 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels); 678 return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
679 } else { 679 } else {
680 ASSERT(operation_cid() == kDoubleCid); 680 ASSERT(operation_cid() == kDoubleCid);
681 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels); 681 return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
682 } 682 }
683 } 683 }
684 684
685 685
686 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 686 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
687 __ TraceSimMsg("RelationalOpInstr"); 687 __ TraceSimMsg("RelationalOpInstr");
688 688
689 Label is_true, is_false; 689 Label is_true, is_false;
690 BranchLabels labels = { &is_true, &is_false, &is_false }; 690 BranchLabels labels = { &is_true, &is_false, &is_false };
691 Condition true_condition = EmitComparisonCode(compiler, labels); 691 Condition true_condition = EmitComparisonCode(compiler, labels);
692 EmitBranchOnCondition(compiler, true_condition, labels); 692 EmitBranchOnCondition(compiler, true_condition, labels);
693 693
694 Register result = locs()->out().reg(); 694 Register result = locs()->out(0).reg();
695 Label done; 695 Label done;
696 __ Bind(&is_false); 696 __ Bind(&is_false);
697 __ LoadObject(result, Bool::False()); 697 __ LoadObject(result, Bool::False());
698 __ b(&done); 698 __ b(&done);
699 __ Bind(&is_true); 699 __ Bind(&is_true);
700 __ LoadObject(result, Bool::True()); 700 __ LoadObject(result, Bool::True());
701 __ Bind(&done); 701 __ Bind(&done);
702 } 702 }
703 703
704 704
705 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 705 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
706 BranchInstr* branch) { 706 BranchInstr* branch) {
707 __ TraceSimMsg("RelationalOpInstr"); 707 __ TraceSimMsg("RelationalOpInstr");
708 708
709 BranchLabels labels = compiler->CreateBranchLabels(branch); 709 BranchLabels labels = compiler->CreateBranchLabels(branch);
710 Condition true_condition = EmitComparisonCode(compiler, labels); 710 Condition true_condition = EmitComparisonCode(compiler, labels);
711 EmitBranchOnCondition(compiler, true_condition, labels); 711 EmitBranchOnCondition(compiler, true_condition, labels);
712 } 712 }
713 713
714 714
715 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { 715 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
716 const intptr_t kNumInputs = 0; 716 const intptr_t kNumInputs = 0;
717 const intptr_t kNumTemps = 3; 717 const intptr_t kNumTemps = 3;
718 LocationSummary* locs = 718 LocationSummary* locs =
719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 719 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
720 locs->set_temp(0, Location::RegisterLocation(A1)); 720 locs->set_temp(0, Location::RegisterLocation(A1));
721 locs->set_temp(1, Location::RegisterLocation(A2)); 721 locs->set_temp(1, Location::RegisterLocation(A2));
722 locs->set_temp(2, Location::RegisterLocation(T5)); 722 locs->set_temp(2, Location::RegisterLocation(T5));
723 locs->set_out(Location::RegisterLocation(V0)); 723 locs->set_out(0, Location::RegisterLocation(V0));
724 return locs; 724 return locs;
725 } 725 }
726 726
727 727
728 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 728 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
729 __ TraceSimMsg("NativeCallInstr"); 729 __ TraceSimMsg("NativeCallInstr");
730 ASSERT(locs()->temp(0).reg() == A1); 730 ASSERT(locs()->temp(0).reg() == A1);
731 ASSERT(locs()->temp(1).reg() == A2); 731 ASSERT(locs()->temp(1).reg() == A2);
732 ASSERT(locs()->temp(2).reg() == T5); 732 ASSERT(locs()->temp(2).reg() == T5);
733 Register result = locs()->out().reg(); 733 Register result = locs()->out(0).reg();
734 734
735 // Push the result place holder initialized to NULL. 735 // Push the result place holder initialized to NULL.
736 __ PushObject(Object::ZoneHandle()); 736 __ PushObject(Object::ZoneHandle());
737 // Pass a pointer to the first argument in A2. 737 // Pass a pointer to the first argument in A2.
738 if (!function().HasOptionalParameters()) { 738 if (!function().HasOptionalParameters()) {
739 __ AddImmediate(A2, FP, (kParamEndSlotFromFp + 739 __ AddImmediate(A2, FP, (kParamEndSlotFromFp +
740 function().NumParameters()) * kWordSize); 740 function().NumParameters()) * kWordSize);
741 } else { 741 } else {
742 __ AddImmediate(A2, FP, kFirstLocalSlotFromFp * kWordSize); 742 __ AddImmediate(A2, FP, kFirstLocalSlotFromFp * kWordSize);
743 } 743 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 const intptr_t kNumInputs = 1; 778 const intptr_t kNumInputs = 1;
779 // TODO(fschneider): Allow immediate operands for the char code. 779 // TODO(fschneider): Allow immediate operands for the char code.
780 return LocationSummary::Make(kNumInputs, 780 return LocationSummary::Make(kNumInputs,
781 Location::RequiresRegister(), 781 Location::RequiresRegister(),
782 LocationSummary::kNoCall); 782 LocationSummary::kNoCall);
783 } 783 }
784 784
785 785
786 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 786 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
787 Register char_code = locs()->in(0).reg(); 787 Register char_code = locs()->in(0).reg();
788 Register result = locs()->out().reg(); 788 Register result = locs()->out(0).reg();
789 789
790 __ TraceSimMsg("StringFromCharCodeInstr"); 790 __ TraceSimMsg("StringFromCharCodeInstr");
791 791
792 __ LoadImmediate(result, 792 __ LoadImmediate(result,
793 reinterpret_cast<uword>(Symbols::PredefinedAddress())); 793 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
794 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); 794 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
795 __ sll(TMP, char_code, 1); // Char code is a smi. 795 __ sll(TMP, char_code, 1); // Char code is a smi.
796 __ addu(TMP, TMP, result); 796 __ addu(TMP, TMP, result);
797 __ lw(result, Address(TMP)); 797 __ lw(result, Address(TMP));
798 } 798 }
799 799
800 800
801 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { 801 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const {
802 const intptr_t kNumInputs = 1; 802 const intptr_t kNumInputs = 1;
803 return LocationSummary::Make(kNumInputs, 803 return LocationSummary::Make(kNumInputs,
804 Location::RequiresRegister(), 804 Location::RequiresRegister(),
805 LocationSummary::kNoCall); 805 LocationSummary::kNoCall);
806 } 806 }
807 807
808 808
809 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 809 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
810 __ TraceSimMsg("StringToCharCodeInstr"); 810 __ TraceSimMsg("StringToCharCodeInstr");
811 811
812 ASSERT(cid_ == kOneByteStringCid); 812 ASSERT(cid_ == kOneByteStringCid);
813 Register str = locs()->in(0).reg(); 813 Register str = locs()->in(0).reg();
814 Register result = locs()->out().reg(); 814 Register result = locs()->out(0).reg();
815 Label done, is_one; 815 Label done, is_one;
816 __ lw(result, FieldAddress(str, String::length_offset())); 816 __ lw(result, FieldAddress(str, String::length_offset()));
817 __ BranchEqual(result, Smi::RawValue(1), &is_one); 817 __ BranchEqual(result, Smi::RawValue(1), &is_one);
818 __ LoadImmediate(result, Smi::RawValue(-1)); 818 __ LoadImmediate(result, Smi::RawValue(-1));
819 __ b(&done); 819 __ b(&done);
820 __ Bind(&is_one); 820 __ Bind(&is_one);
821 __ lbu(result, FieldAddress(str, OneByteString::data_offset())); 821 __ lbu(result, FieldAddress(str, OneByteString::data_offset()));
822 __ SmiTag(result); 822 __ SmiTag(result);
823 __ Bind(&done); 823 __ Bind(&done);
824 } 824 }
825 825
826 826
827 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { 827 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const {
828 const intptr_t kNumInputs = 1; 828 const intptr_t kNumInputs = 1;
829 const intptr_t kNumTemps = 0; 829 const intptr_t kNumTemps = 0;
830 LocationSummary* summary = 830 LocationSummary* summary =
831 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 831 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
832 summary->set_in(0, Location::RegisterLocation(A0)); 832 summary->set_in(0, Location::RegisterLocation(A0));
833 summary->set_out(Location::RegisterLocation(V0)); 833 summary->set_out(0, Location::RegisterLocation(V0));
834 return summary; 834 return summary;
835 } 835 }
836 836
837 837
838 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 838 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
839 Register array = locs()->in(0).reg(); 839 Register array = locs()->in(0).reg();
840 __ Push(array); 840 __ Push(array);
841 const int kNumberOfArguments = 1; 841 const int kNumberOfArguments = 1;
842 const Array& kNoArgumentNames = Object::null_array(); 842 const Array& kNoArgumentNames = Object::null_array();
843 compiler->GenerateStaticCall(deopt_id(), 843 compiler->GenerateStaticCall(deopt_id(),
844 token_pos(), 844 token_pos(),
845 CallFunction(), 845 CallFunction(),
846 kNumberOfArguments, 846 kNumberOfArguments,
847 kNoArgumentNames, 847 kNoArgumentNames,
848 locs()); 848 locs());
849 ASSERT(locs()->out().reg() == V0); 849 ASSERT(locs()->out(0).reg() == V0);
850 } 850 }
851 851
852 852
853 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { 853 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const {
854 const intptr_t kNumInputs = 1; 854 const intptr_t kNumInputs = 1;
855 return LocationSummary::Make(kNumInputs, 855 return LocationSummary::Make(kNumInputs,
856 Location::RequiresRegister(), 856 Location::RequiresRegister(),
857 LocationSummary::kNoCall); 857 LocationSummary::kNoCall);
858 } 858 }
859 859
860 860
861 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 861 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
862 Register object = locs()->in(0).reg(); 862 Register object = locs()->in(0).reg();
863 Register result = locs()->out().reg(); 863 Register result = locs()->out(0).reg();
864 __ LoadFromOffset(result, object, offset() - kHeapObjectTag); 864 __ LoadFromOffset(result, object, offset() - kHeapObjectTag);
865 } 865 }
866 866
867 867
868 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { 868 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const {
869 const intptr_t kNumInputs = 1; 869 const intptr_t kNumInputs = 1;
870 return LocationSummary::Make(kNumInputs, 870 return LocationSummary::Make(kNumInputs,
871 Location::RequiresRegister(), 871 Location::RequiresRegister(),
872 LocationSummary::kNoCall); 872 LocationSummary::kNoCall);
873 } 873 }
874 874
875 875
876 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 876 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
877 Register object = locs()->in(0).reg(); 877 Register object = locs()->in(0).reg();
878 Register result = locs()->out().reg(); 878 Register result = locs()->out(0).reg();
879 Label load, done; 879 Label load, done;
880 __ andi(CMPRES1, object, Immediate(kSmiTagMask)); 880 __ andi(CMPRES1, object, Immediate(kSmiTagMask));
881 __ bne(CMPRES1, ZR, &load); 881 __ bne(CMPRES1, ZR, &load);
882 __ LoadImmediate(result, Smi::RawValue(kSmiCid)); 882 __ LoadImmediate(result, Smi::RawValue(kSmiCid));
883 __ b(&done); 883 __ b(&done);
884 __ Bind(&load); 884 __ Bind(&load);
885 __ LoadClassId(result, object); 885 __ LoadClassId(result, object);
886 __ SmiTag(result); 886 __ SmiTag(result);
887 __ Bind(&done); 887 __ Bind(&done);
888 } 888 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 LocationSummary* locs = 967 LocationSummary* locs =
968 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 968 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
969 locs->set_in(0, Location::RequiresRegister()); 969 locs->set_in(0, Location::RequiresRegister());
970 // The smi index is either untagged (element size == 1), or it is left smi 970 // The smi index is either untagged (element size == 1), or it is left smi
971 // tagged (for all element sizes > 1). 971 // tagged (for all element sizes > 1).
972 // TODO(regis): Revisit and see if the index can be immediate. 972 // TODO(regis): Revisit and see if the index can be immediate.
973 locs->set_in(1, Location::WritableRegister()); 973 locs->set_in(1, Location::WritableRegister());
974 if ((representation() == kUnboxedDouble) || 974 if ((representation() == kUnboxedDouble) ||
975 (representation() == kUnboxedFloat32x4) || 975 (representation() == kUnboxedFloat32x4) ||
976 (representation() == kUnboxedInt32x4)) { 976 (representation() == kUnboxedInt32x4)) {
977 locs->set_out(Location::RequiresFpuRegister()); 977 locs->set_out(0, Location::RequiresFpuRegister());
978 } else { 978 } else {
979 locs->set_out(Location::RequiresRegister()); 979 locs->set_out(0, Location::RequiresRegister());
980 } 980 }
981 return locs; 981 return locs;
982 } 982 }
983 983
984 984
985 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 985 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
986 __ TraceSimMsg("LoadIndexedInstr"); 986 __ TraceSimMsg("LoadIndexedInstr");
987 Register array = locs()->in(0).reg(); 987 Register array = locs()->in(0).reg();
988 Location index = locs()->in(1); 988 Location index = locs()->in(1);
989 989
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 // mode, then we must load the offset into a register and add it to the 1027 // mode, then we must load the offset into a register and add it to the
1028 // index. 1028 // index.
1029 element_address = Address(index.reg(), 1029 element_address = Address(index.reg(),
1030 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1030 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1031 } 1031 }
1032 1032
1033 if ((representation() == kUnboxedDouble) || 1033 if ((representation() == kUnboxedDouble) ||
1034 (representation() == kUnboxedMint) || 1034 (representation() == kUnboxedMint) ||
1035 (representation() == kUnboxedFloat32x4) || 1035 (representation() == kUnboxedFloat32x4) ||
1036 (representation() == kUnboxedInt32x4)) { 1036 (representation() == kUnboxedInt32x4)) {
1037 DRegister result = locs()->out().fpu_reg(); 1037 DRegister result = locs()->out(0).fpu_reg();
1038 switch (class_id()) { 1038 switch (class_id()) {
1039 case kTypedDataInt32ArrayCid: 1039 case kTypedDataInt32ArrayCid:
1040 UNIMPLEMENTED(); 1040 UNIMPLEMENTED();
1041 break; 1041 break;
1042 case kTypedDataUint32ArrayCid: 1042 case kTypedDataUint32ArrayCid:
1043 UNIMPLEMENTED(); 1043 UNIMPLEMENTED();
1044 break; 1044 break;
1045 case kTypedDataFloat32ArrayCid: 1045 case kTypedDataFloat32ArrayCid:
1046 // Load single precision float. 1046 // Load single precision float.
1047 __ lwc1(EvenFRegisterOf(result), element_address); 1047 __ lwc1(EvenFRegisterOf(result), element_address);
1048 break; 1048 break;
1049 case kTypedDataFloat64ArrayCid: 1049 case kTypedDataFloat64ArrayCid:
1050 __ LoadDFromOffset(result, index.reg(), 1050 __ LoadDFromOffset(result, index.reg(),
1051 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1051 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1052 break; 1052 break;
1053 case kTypedDataInt32x4ArrayCid: 1053 case kTypedDataInt32x4ArrayCid:
1054 case kTypedDataFloat32x4ArrayCid: 1054 case kTypedDataFloat32x4ArrayCid:
1055 UNIMPLEMENTED(); 1055 UNIMPLEMENTED();
1056 break; 1056 break;
1057 } 1057 }
1058 return; 1058 return;
1059 } 1059 }
1060 1060
1061 Register result = locs()->out().reg(); 1061 Register result = locs()->out(0).reg();
1062 switch (class_id()) { 1062 switch (class_id()) {
1063 case kTypedDataInt8ArrayCid: 1063 case kTypedDataInt8ArrayCid:
1064 ASSERT(index_scale() == 1); 1064 ASSERT(index_scale() == 1);
1065 __ lb(result, element_address); 1065 __ lb(result, element_address);
1066 __ SmiTag(result); 1066 __ SmiTag(result);
1067 break; 1067 break;
1068 case kTypedDataUint8ArrayCid: 1068 case kTypedDataUint8ArrayCid:
1069 case kTypedDataUint8ClampedArrayCid: 1069 case kTypedDataUint8ClampedArrayCid:
1070 case kExternalTypedDataUint8ArrayCid: 1070 case kExternalTypedDataUint8ArrayCid:
1071 case kExternalTypedDataUint8ClampedArrayCid: 1071 case kExternalTypedDataUint8ClampedArrayCid:
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
1661 : instruction_(instruction), cls_(cls) { } 1661 : instruction_(instruction), cls_(cls) { }
1662 1662
1663 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1663 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1664 __ Comment("StoreInstanceFieldSlowPath"); 1664 __ Comment("StoreInstanceFieldSlowPath");
1665 __ Bind(entry_label()); 1665 __ Bind(entry_label());
1666 const Code& stub = 1666 const Code& stub =
1667 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1667 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1668 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1668 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1669 1669
1670 LocationSummary* locs = instruction_->locs(); 1670 LocationSummary* locs = instruction_->locs();
1671 locs->live_registers()->Remove(locs->out()); 1671 locs->live_registers()->Remove(locs->out(0));
1672 1672
1673 compiler->SaveLiveRegisters(locs); 1673 compiler->SaveLiveRegisters(locs);
1674 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1674 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1675 &label, 1675 &label,
1676 PcDescriptors::kOther, 1676 PcDescriptors::kOther,
1677 locs); 1677 locs);
1678 __ mov(locs->temp(0).reg(), V0); 1678 __ mov(locs->temp(0).reg(), V0);
1679 compiler->RestoreLiveRegisters(locs); 1679 compiler->RestoreLiveRegisters(locs);
1680 1680
1681 __ b(exit_label()); 1681 __ b(exit_label());
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 __ Bind(&skip_store); 1850 __ Bind(&skip_store);
1851 } 1851 }
1852 1852
1853 1853
1854 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { 1854 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1855 const intptr_t kNumInputs = 1; 1855 const intptr_t kNumInputs = 1;
1856 const intptr_t kNumTemps = 0; 1856 const intptr_t kNumTemps = 0;
1857 LocationSummary* summary = 1857 LocationSummary* summary =
1858 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1858 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1859 summary->set_in(0, Location::RequiresRegister()); 1859 summary->set_in(0, Location::RequiresRegister());
1860 summary->set_out(Location::RequiresRegister()); 1860 summary->set_out(0, Location::RequiresRegister());
1861 return summary; 1861 return summary;
1862 } 1862 }
1863 1863
1864 1864
1865 // When the parser is building an implicit static getter for optimization, 1865 // When the parser is building an implicit static getter for optimization,
1866 // it can generate a function body where deoptimization ids do not line up 1866 // it can generate a function body where deoptimization ids do not line up
1867 // with the unoptimized code. 1867 // with the unoptimized code.
1868 // 1868 //
1869 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1869 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1870 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1870 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1871 __ TraceSimMsg("LoadStaticFieldInstr"); 1871 __ TraceSimMsg("LoadStaticFieldInstr");
1872 Register field = locs()->in(0).reg(); 1872 Register field = locs()->in(0).reg();
1873 Register result = locs()->out().reg(); 1873 Register result = locs()->out(0).reg();
1874 __ lw(result, FieldAddress(field, Field::value_offset())); 1874 __ lw(result, FieldAddress(field, Field::value_offset()));
1875 } 1875 }
1876 1876
1877 1877
1878 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { 1878 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const {
1879 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1879 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1880 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1880 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1881 : Location::RequiresRegister()); 1881 : Location::RequiresRegister());
1882 locs->set_temp(0, Location::RequiresRegister()); 1882 locs->set_temp(0, Location::RequiresRegister());
1883 return locs; 1883 return locs;
(...skipping 17 matching lines...) Expand all
1901 1901
1902 1902
1903 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { 1903 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1904 const intptr_t kNumInputs = 3; 1904 const intptr_t kNumInputs = 3;
1905 const intptr_t kNumTemps = 0; 1905 const intptr_t kNumTemps = 0;
1906 LocationSummary* summary = 1906 LocationSummary* summary =
1907 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1907 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1908 summary->set_in(0, Location::RegisterLocation(A0)); 1908 summary->set_in(0, Location::RegisterLocation(A0));
1909 summary->set_in(1, Location::RegisterLocation(A2)); 1909 summary->set_in(1, Location::RegisterLocation(A2));
1910 summary->set_in(2, Location::RegisterLocation(A1)); 1910 summary->set_in(2, Location::RegisterLocation(A1));
1911 summary->set_out(Location::RegisterLocation(V0)); 1911 summary->set_out(0, Location::RegisterLocation(V0));
1912 return summary; 1912 return summary;
1913 } 1913 }
1914 1914
1915 1915
1916 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1916 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1917 ASSERT(locs()->in(0).reg() == A0); // Value. 1917 ASSERT(locs()->in(0).reg() == A0); // Value.
1918 ASSERT(locs()->in(1).reg() == A2); // Instantiator. 1918 ASSERT(locs()->in(1).reg() == A2); // Instantiator.
1919 ASSERT(locs()->in(2).reg() == A1); // Instantiator type arguments. 1919 ASSERT(locs()->in(2).reg() == A1); // Instantiator type arguments.
1920 1920
1921 __ Comment("InstanceOfInstr"); 1921 __ Comment("InstanceOfInstr");
1922 compiler->GenerateInstanceOf(token_pos(), 1922 compiler->GenerateInstanceOf(token_pos(),
1923 deopt_id(), 1923 deopt_id(),
1924 type(), 1924 type(),
1925 negate_result(), 1925 negate_result(),
1926 locs()); 1926 locs());
1927 ASSERT(locs()->out().reg() == V0); 1927 ASSERT(locs()->out(0).reg() == V0);
1928 } 1928 }
1929 1929
1930 1930
1931 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { 1931 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const {
1932 const intptr_t kNumInputs = 2; 1932 const intptr_t kNumInputs = 2;
1933 const intptr_t kNumTemps = 0; 1933 const intptr_t kNumTemps = 0;
1934 LocationSummary* locs = 1934 LocationSummary* locs =
1935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1935 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1936 locs->set_in(0, Location::RegisterLocation(A0)); 1936 locs->set_in(0, Location::RegisterLocation(A0));
1937 locs->set_in(1, Location::RegisterLocation(A1)); 1937 locs->set_in(1, Location::RegisterLocation(A1));
1938 locs->set_out(Location::RegisterLocation(V0)); 1938 locs->set_out(0, Location::RegisterLocation(V0));
1939 return locs; 1939 return locs;
1940 } 1940 }
1941 1941
1942 1942
1943 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1943 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1944 __ TraceSimMsg("CreateArrayInstr"); 1944 __ TraceSimMsg("CreateArrayInstr");
1945 // Allocate the array. A1 = length, A0 = element type. 1945 // Allocate the array. A1 = length, A0 = element type.
1946 ASSERT(locs()->in(0).reg() == A0); 1946 ASSERT(locs()->in(0).reg() == A0);
1947 ASSERT(locs()->in(1).reg() == A1); 1947 ASSERT(locs()->in(1).reg() == A1);
1948 compiler->GenerateCall(token_pos(), 1948 compiler->GenerateCall(token_pos(),
1949 &StubCode::AllocateArrayLabel(), 1949 &StubCode::AllocateArrayLabel(),
1950 PcDescriptors::kOther, 1950 PcDescriptors::kOther,
1951 locs()); 1951 locs());
1952 ASSERT(locs()->out().reg() == V0); 1952 ASSERT(locs()->out(0).reg() == V0);
1953 } 1953 }
1954 1954
1955 1955
1956 class BoxDoubleSlowPath : public SlowPathCode { 1956 class BoxDoubleSlowPath : public SlowPathCode {
1957 public: 1957 public:
1958 explicit BoxDoubleSlowPath(Instruction* instruction) 1958 explicit BoxDoubleSlowPath(Instruction* instruction)
1959 : instruction_(instruction) { } 1959 : instruction_(instruction) { }
1960 1960
1961 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1961 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1962 __ Comment("BoxDoubleSlowPath"); 1962 __ Comment("BoxDoubleSlowPath");
1963 __ Bind(entry_label()); 1963 __ Bind(entry_label());
1964 const Class& double_class = compiler->double_class(); 1964 const Class& double_class = compiler->double_class();
1965 const Code& stub = 1965 const Code& stub =
1966 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1966 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1967 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1967 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1968 1968
1969 LocationSummary* locs = instruction_->locs(); 1969 LocationSummary* locs = instruction_->locs();
1970 locs->live_registers()->Remove(locs->out()); 1970 locs->live_registers()->Remove(locs->out(0));
1971 1971
1972 compiler->SaveLiveRegisters(locs); 1972 compiler->SaveLiveRegisters(locs);
1973 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1973 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1974 &label, 1974 &label,
1975 PcDescriptors::kOther, 1975 PcDescriptors::kOther,
1976 locs); 1976 locs);
1977 if (locs->out().reg() != V0) { 1977 if (locs->out(0).reg() != V0) {
1978 __ mov(locs->out().reg(), V0); 1978 __ mov(locs->out(0).reg(), V0);
1979 } 1979 }
1980 compiler->RestoreLiveRegisters(locs); 1980 compiler->RestoreLiveRegisters(locs);
1981 1981
1982 __ b(exit_label()); 1982 __ b(exit_label());
1983 } 1983 }
1984 1984
1985 private: 1985 private:
1986 Instruction* instruction_; 1986 Instruction* instruction_;
1987 }; 1987 };
1988 1988
(...skipping 10 matching lines...) Expand all
1999 1999
2000 locs->set_in(0, Location::RequiresRegister()); 2000 locs->set_in(0, Location::RequiresRegister());
2001 2001
2002 if (IsUnboxedLoad() && opt) { 2002 if (IsUnboxedLoad() && opt) {
2003 locs->AddTemp(Location::RequiresRegister()); 2003 locs->AddTemp(Location::RequiresRegister());
2004 } else if (IsPotentialUnboxedLoad()) { 2004 } else if (IsPotentialUnboxedLoad()) {
2005 locs->AddTemp(opt ? Location::RequiresFpuRegister() 2005 locs->AddTemp(opt ? Location::RequiresFpuRegister()
2006 : Location::FpuRegisterLocation(D1)); 2006 : Location::FpuRegisterLocation(D1));
2007 locs->AddTemp(Location::RequiresRegister()); 2007 locs->AddTemp(Location::RequiresRegister());
2008 } 2008 }
2009 locs->set_out(Location::RequiresRegister()); 2009 locs->set_out(0, Location::RequiresRegister());
2010 return locs; 2010 return locs;
2011 } 2011 }
2012 2012
2013 2013
2014 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2014 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2015 Register instance_reg = locs()->in(0).reg(); 2015 Register instance_reg = locs()->in(0).reg();
2016 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2016 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2017 DRegister result = locs()->out().fpu_reg(); 2017 DRegister result = locs()->out(0).fpu_reg();
2018 Register temp = locs()->temp(0).reg(); 2018 Register temp = locs()->temp(0).reg();
2019 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes())); 2019 __ lw(temp, FieldAddress(instance_reg, offset_in_bytes()));
2020 intptr_t cid = field()->UnboxedFieldCid(); 2020 intptr_t cid = field()->UnboxedFieldCid();
2021 switch (cid) { 2021 switch (cid) {
2022 case kDoubleCid: 2022 case kDoubleCid:
2023 __ LoadDFromOffset(result, temp, 2023 __ LoadDFromOffset(result, temp,
2024 Double::value_offset() - kHeapObjectTag); 2024 Double::value_offset() - kHeapObjectTag);
2025 break; 2025 break;
2026 default: 2026 default:
2027 UNREACHABLE(); 2027 UNREACHABLE();
2028 } 2028 }
2029 return; 2029 return;
2030 } 2030 }
2031 2031
2032 Label done; 2032 Label done;
2033 Register result_reg = locs()->out().reg(); 2033 Register result_reg = locs()->out(0).reg();
2034 if (IsPotentialUnboxedLoad()) { 2034 if (IsPotentialUnboxedLoad()) {
2035 Register temp = locs()->temp(1).reg(); 2035 Register temp = locs()->temp(1).reg();
2036 DRegister value = locs()->temp(0).fpu_reg(); 2036 DRegister value = locs()->temp(0).fpu_reg();
2037 2037
2038 Label load_pointer; 2038 Label load_pointer;
2039 Label load_double; 2039 Label load_double;
2040 2040
2041 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 2041 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
2042 2042
2043 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 2043 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 __ Bind(&done); 2081 __ Bind(&done);
2082 } 2082 }
2083 2083
2084 2084
2085 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2085 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
2086 const intptr_t kNumInputs = 1; 2086 const intptr_t kNumInputs = 1;
2087 const intptr_t kNumTemps = 0; 2087 const intptr_t kNumTemps = 0;
2088 LocationSummary* locs = 2088 LocationSummary* locs =
2089 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2089 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2090 locs->set_in(0, Location::RegisterLocation(T0)); 2090 locs->set_in(0, Location::RegisterLocation(T0));
2091 locs->set_out(Location::RegisterLocation(T0)); 2091 locs->set_out(0, Location::RegisterLocation(T0));
2092 return locs; 2092 return locs;
2093 } 2093 }
2094 2094
2095 2095
2096 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2096 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2097 __ TraceSimMsg("InstantiateTypeInstr"); 2097 __ TraceSimMsg("InstantiateTypeInstr");
2098 Register instantiator_reg = locs()->in(0).reg(); 2098 Register instantiator_reg = locs()->in(0).reg();
2099 Register result_reg = locs()->out().reg(); 2099 Register result_reg = locs()->out(0).reg();
2100 2100
2101 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2101 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2102 // A runtime call to instantiate the type is required. 2102 // A runtime call to instantiate the type is required.
2103 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 2103 __ addiu(SP, SP, Immediate(-3 * kWordSize));
2104 __ LoadObject(TMP, Object::ZoneHandle()); 2104 __ LoadObject(TMP, Object::ZoneHandle());
2105 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result. 2105 __ sw(TMP, Address(SP, 2 * kWordSize)); // Make room for the result.
2106 __ LoadObject(TMP, type()); 2106 __ LoadObject(TMP, type());
2107 __ sw(TMP, Address(SP, 1 * kWordSize)); 2107 __ sw(TMP, Address(SP, 1 * kWordSize));
2108 // Push instantiator type arguments. 2108 // Push instantiator type arguments.
2109 __ sw(instantiator_reg, Address(SP, 0 * kWordSize)); 2109 __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
(...skipping 11 matching lines...) Expand all
2121 } 2121 }
2122 2122
2123 2123
2124 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( 2124 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2125 bool opt) const { 2125 bool opt) const {
2126 const intptr_t kNumInputs = 1; 2126 const intptr_t kNumInputs = 1;
2127 const intptr_t kNumTemps = 0; 2127 const intptr_t kNumTemps = 0;
2128 LocationSummary* locs = 2128 LocationSummary* locs =
2129 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2129 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2130 locs->set_in(0, Location::RegisterLocation(T0)); 2130 locs->set_in(0, Location::RegisterLocation(T0));
2131 locs->set_out(Location::RegisterLocation(T0)); 2131 locs->set_out(0, Location::RegisterLocation(T0));
2132 return locs; 2132 return locs;
2133 } 2133 }
2134 2134
2135 2135
2136 void InstantiateTypeArgumentsInstr::EmitNativeCode( 2136 void InstantiateTypeArgumentsInstr::EmitNativeCode(
2137 FlowGraphCompiler* compiler) { 2137 FlowGraphCompiler* compiler) {
2138 __ TraceSimMsg("InstantiateTypeArgumentsInstr"); 2138 __ TraceSimMsg("InstantiateTypeArgumentsInstr");
2139 Register instantiator_reg = locs()->in(0).reg(); 2139 Register instantiator_reg = locs()->in(0).reg();
2140 Register result_reg = locs()->out().reg(); 2140 Register result_reg = locs()->out(0).reg();
2141 ASSERT(instantiator_reg == T0); 2141 ASSERT(instantiator_reg == T0);
2142 ASSERT(instantiator_reg == result_reg); 2142 ASSERT(instantiator_reg == result_reg);
2143 2143
2144 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2144 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2145 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2145 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2146 !type_arguments().CanShareInstantiatorTypeArguments( 2146 !type_arguments().CanShareInstantiatorTypeArguments(
2147 instantiator_class())); 2147 instantiator_class()));
2148 // If the instantiator is null and if the type argument vector 2148 // If the instantiator is null and if the type argument vector
2149 // instantiated from null becomes a vector of dynamic, then use null as 2149 // instantiated from null becomes a vector of dynamic, then use null as
2150 // the type arguments. 2150 // the type arguments.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 __ Bind(&type_arguments_instantiated); 2194 __ Bind(&type_arguments_instantiated);
2195 } 2195 }
2196 2196
2197 2197
2198 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { 2198 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
2199 const intptr_t kNumInputs = 0; 2199 const intptr_t kNumInputs = 0;
2200 const intptr_t kNumTemps = 1; 2200 const intptr_t kNumTemps = 1;
2201 LocationSummary* locs = 2201 LocationSummary* locs =
2202 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2202 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2203 locs->set_temp(0, Location::RegisterLocation(T1)); 2203 locs->set_temp(0, Location::RegisterLocation(T1));
2204 locs->set_out(Location::RegisterLocation(V0)); 2204 locs->set_out(0, Location::RegisterLocation(V0));
2205 return locs; 2205 return locs;
2206 } 2206 }
2207 2207
2208 2208
2209 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2209 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2210 Register temp = T1; 2210 Register temp = T1;
2211 ASSERT(locs()->temp(0).reg() == temp); 2211 ASSERT(locs()->temp(0).reg() == temp);
2212 ASSERT(locs()->out().reg() == V0); 2212 ASSERT(locs()->out(0).reg() == V0);
2213 2213
2214 __ TraceSimMsg("AllocateContextInstr"); 2214 __ TraceSimMsg("AllocateContextInstr");
2215 __ LoadImmediate(temp, num_context_variables()); 2215 __ LoadImmediate(temp, num_context_variables());
2216 const ExternalLabel label("alloc_context", 2216 const ExternalLabel label("alloc_context",
2217 StubCode::AllocateContextEntryPoint()); 2217 StubCode::AllocateContextEntryPoint());
2218 compiler->GenerateCall(token_pos(), 2218 compiler->GenerateCall(token_pos(),
2219 &label, 2219 &label,
2220 PcDescriptors::kOther, 2220 PcDescriptors::kOther,
2221 locs()); 2221 locs());
2222 } 2222 }
2223 2223
2224 2224
2225 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { 2225 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const {
2226 const intptr_t kNumInputs = 1; 2226 const intptr_t kNumInputs = 1;
2227 const intptr_t kNumTemps = 0; 2227 const intptr_t kNumTemps = 0;
2228 LocationSummary* locs = 2228 LocationSummary* locs =
2229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2230 locs->set_in(0, Location::RegisterLocation(T0)); 2230 locs->set_in(0, Location::RegisterLocation(T0));
2231 locs->set_out(Location::RegisterLocation(T0)); 2231 locs->set_out(0, Location::RegisterLocation(T0));
2232 return locs; 2232 return locs;
2233 } 2233 }
2234 2234
2235 2235
2236 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2236 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2237 Register context_value = locs()->in(0).reg(); 2237 Register context_value = locs()->in(0).reg();
2238 Register result = locs()->out().reg(); 2238 Register result = locs()->out(0).reg();
2239 2239
2240 __ TraceSimMsg("CloneContextInstr"); 2240 __ TraceSimMsg("CloneContextInstr");
2241 2241
2242 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 2242 __ addiu(SP, SP, Immediate(-2 * kWordSize));
2243 __ LoadObject(TMP, Object::ZoneHandle()); // Make room for the result. 2243 __ LoadObject(TMP, Object::ZoneHandle()); // Make room for the result.
2244 __ sw(TMP, Address(SP, 1 * kWordSize)); 2244 __ sw(TMP, Address(SP, 1 * kWordSize));
2245 __ sw(context_value, Address(SP, 0 * kWordSize)); 2245 __ sw(context_value, Address(SP, 0 * kWordSize));
2246 2246
2247 compiler->GenerateRuntimeCall(token_pos(), 2247 compiler->GenerateRuntimeCall(token_pos(),
2248 deopt_id(), 2248 deopt_id(),
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 } 2365 }
2366 __ Bind(slow_path->exit_label()); 2366 __ Bind(slow_path->exit_label());
2367 } 2367 }
2368 2368
2369 2369
2370 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2370 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2371 BinarySmiOpInstr* shift_left) { 2371 BinarySmiOpInstr* shift_left) {
2372 const bool is_truncating = shift_left->is_truncating(); 2372 const bool is_truncating = shift_left->is_truncating();
2373 const LocationSummary& locs = *shift_left->locs(); 2373 const LocationSummary& locs = *shift_left->locs();
2374 Register left = locs.in(0).reg(); 2374 Register left = locs.in(0).reg();
2375 Register result = locs.out().reg(); 2375 Register result = locs.out(0).reg();
2376 Label* deopt = shift_left->CanDeoptimize() ? 2376 Label* deopt = shift_left->CanDeoptimize() ?
2377 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; 2377 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL;
2378 2378
2379 __ TraceSimMsg("EmitSmiShiftLeft"); 2379 __ TraceSimMsg("EmitSmiShiftLeft");
2380 2380
2381 if (locs.in(1).IsConstant()) { 2381 if (locs.in(1).IsConstant()) {
2382 const Object& constant = locs.in(1).constant(); 2382 const Object& constant = locs.in(1).constant();
2383 ASSERT(constant.IsSmi()); 2383 ASSERT(constant.IsSmi());
2384 // Immediate shift operation takes 5 bits for the count. 2384 // Immediate shift operation takes 5 bits for the count.
2385 const intptr_t kCountLimit = 0x1F; 2385 const intptr_t kCountLimit = 0x1F;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2489 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2489 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2490 if (op_kind() == Token::kTRUNCDIV) { 2490 if (op_kind() == Token::kTRUNCDIV) {
2491 summary->set_in(0, Location::RequiresRegister()); 2491 summary->set_in(0, Location::RequiresRegister());
2492 if (RightIsPowerOfTwoConstant()) { 2492 if (RightIsPowerOfTwoConstant()) {
2493 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2493 ConstantInstr* right_constant = right()->definition()->AsConstant();
2494 summary->set_in(1, Location::Constant(right_constant->value())); 2494 summary->set_in(1, Location::Constant(right_constant->value()));
2495 } else { 2495 } else {
2496 summary->set_in(1, Location::RequiresRegister()); 2496 summary->set_in(1, Location::RequiresRegister());
2497 } 2497 }
2498 summary->AddTemp(Location::RequiresRegister()); 2498 summary->AddTemp(Location::RequiresRegister());
2499 summary->set_out(Location::RequiresRegister()); 2499 summary->set_out(0, Location::RequiresRegister());
2500 return summary; 2500 return summary;
2501 } 2501 }
2502 if (op_kind() == Token::kMOD) { 2502 if (op_kind() == Token::kMOD) {
2503 summary->set_in(0, Location::RequiresRegister()); 2503 summary->set_in(0, Location::RequiresRegister());
2504 summary->set_in(1, Location::RequiresRegister()); 2504 summary->set_in(1, Location::RequiresRegister());
2505 summary->AddTemp(Location::RequiresRegister()); 2505 summary->AddTemp(Location::RequiresRegister());
2506 summary->set_out(Location::RequiresRegister()); 2506 summary->set_out(0, Location::RequiresRegister());
2507 return summary; 2507 return summary;
2508 } 2508 }
2509 summary->set_in(0, Location::RequiresRegister()); 2509 summary->set_in(0, Location::RequiresRegister());
2510 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2510 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2511 if (((op_kind() == Token::kSHL) && !is_truncating()) || 2511 if (((op_kind() == Token::kSHL) && !is_truncating()) ||
2512 (op_kind() == Token::kSHR)) { 2512 (op_kind() == Token::kSHR)) {
2513 summary->AddTemp(Location::RequiresRegister()); 2513 summary->AddTemp(Location::RequiresRegister());
2514 } else if (op_kind() == Token::kADD) { 2514 } else if (op_kind() == Token::kADD) {
2515 // Need an extra temp for the overflow detection code. 2515 // Need an extra temp for the overflow detection code.
2516 summary->set_temp(0, Location::RequiresRegister()); 2516 summary->set_temp(0, Location::RequiresRegister());
2517 } 2517 }
2518 // We make use of 3-operand instructions by not requiring result register 2518 // We make use of 3-operand instructions by not requiring result register
2519 // to be identical to first input register as on Intel. 2519 // to be identical to first input register as on Intel.
2520 summary->set_out(Location::RequiresRegister()); 2520 summary->set_out(0, Location::RequiresRegister());
2521 return summary; 2521 return summary;
2522 } 2522 }
2523 2523
2524 2524
2525 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2525 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2526 __ TraceSimMsg("BinarySmiOpInstr"); 2526 __ TraceSimMsg("BinarySmiOpInstr");
2527 if (op_kind() == Token::kSHL) { 2527 if (op_kind() == Token::kSHL) {
2528 EmitSmiShiftLeft(compiler, this); 2528 EmitSmiShiftLeft(compiler, this);
2529 return; 2529 return;
2530 } 2530 }
2531 2531
2532 ASSERT(!is_truncating()); 2532 ASSERT(!is_truncating());
2533 Register left = locs()->in(0).reg(); 2533 Register left = locs()->in(0).reg();
2534 Register result = locs()->out().reg(); 2534 Register result = locs()->out(0).reg();
2535 Label* deopt = NULL; 2535 Label* deopt = NULL;
2536 if (CanDeoptimize()) { 2536 if (CanDeoptimize()) {
2537 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 2537 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
2538 } 2538 }
2539 2539
2540 if (locs()->in(1).IsConstant()) { 2540 if (locs()->in(1).IsConstant()) {
2541 const Object& constant = locs()->in(1).constant(); 2541 const Object& constant = locs()->in(1).constant();
2542 ASSERT(constant.IsSmi()); 2542 ASSERT(constant.IsSmi());
2543 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); 2543 int32_t imm = reinterpret_cast<int32_t>(constant.raw());
2544 switch (op_kind()) { 2544 switch (op_kind()) {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
2862 2862
2863 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 2863 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2864 const intptr_t kNumInputs = 1; 2864 const intptr_t kNumInputs = 1;
2865 const intptr_t kNumTemps = 1; 2865 const intptr_t kNumTemps = 1;
2866 LocationSummary* summary = 2866 LocationSummary* summary =
2867 new LocationSummary(kNumInputs, 2867 new LocationSummary(kNumInputs,
2868 kNumTemps, 2868 kNumTemps,
2869 LocationSummary::kCallOnSlowPath); 2869 LocationSummary::kCallOnSlowPath);
2870 summary->set_in(0, Location::RequiresFpuRegister()); 2870 summary->set_in(0, Location::RequiresFpuRegister());
2871 summary->set_temp(0, Location::RequiresRegister()); 2871 summary->set_temp(0, Location::RequiresRegister());
2872 summary->set_out(Location::RequiresRegister()); 2872 summary->set_out(0, Location::RequiresRegister());
2873 return summary; 2873 return summary;
2874 } 2874 }
2875 2875
2876 2876
2877 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2877 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2878 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2878 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2879 compiler->AddSlowPathCode(slow_path); 2879 compiler->AddSlowPathCode(slow_path);
2880 2880
2881 Register out_reg = locs()->out().reg(); 2881 Register out_reg = locs()->out(0).reg();
2882 DRegister value = locs()->in(0).fpu_reg(); 2882 DRegister value = locs()->in(0).fpu_reg();
2883 2883
2884 __ TryAllocate(compiler->double_class(), 2884 __ TryAllocate(compiler->double_class(),
2885 slow_path->entry_label(), 2885 slow_path->entry_label(),
2886 out_reg, 2886 out_reg,
2887 locs()->temp(0).reg()); 2887 locs()->temp(0).reg());
2888 __ Bind(slow_path->exit_label()); 2888 __ Bind(slow_path->exit_label());
2889 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); 2889 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
2890 } 2890 }
2891 2891
2892 2892
2893 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { 2893 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
2894 const intptr_t kNumInputs = 1; 2894 const intptr_t kNumInputs = 1;
2895 const intptr_t value_cid = value()->Type()->ToCid(); 2895 const intptr_t value_cid = value()->Type()->ToCid();
2896 const bool needs_writable_input = (value_cid == kSmiCid); 2896 const bool needs_writable_input = (value_cid == kSmiCid);
2897 const intptr_t kNumTemps = 0; 2897 const intptr_t kNumTemps = 0;
2898 LocationSummary* summary = 2898 LocationSummary* summary =
2899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2900 summary->set_in(0, needs_writable_input 2900 summary->set_in(0, needs_writable_input
2901 ? Location::WritableRegister() 2901 ? Location::WritableRegister()
2902 : Location::RequiresRegister()); 2902 : Location::RequiresRegister());
2903 summary->set_out(Location::RequiresFpuRegister()); 2903 summary->set_out(0, Location::RequiresFpuRegister());
2904 return summary; 2904 return summary;
2905 } 2905 }
2906 2906
2907 2907
2908 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2908 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2909 const intptr_t value_cid = value()->Type()->ToCid(); 2909 const intptr_t value_cid = value()->Type()->ToCid();
2910 const Register value = locs()->in(0).reg(); 2910 const Register value = locs()->in(0).reg();
2911 const DRegister result = locs()->out().fpu_reg(); 2911 const DRegister result = locs()->out(0).fpu_reg();
2912 2912
2913 if (value_cid == kDoubleCid) { 2913 if (value_cid == kDoubleCid) {
2914 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); 2914 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
2915 } else if (value_cid == kSmiCid) { 2915 } else if (value_cid == kSmiCid) {
2916 __ SmiUntag(value); // Untag input before conversion. 2916 __ SmiUntag(value); // Untag input before conversion.
2917 __ mtc1(value, STMP1); 2917 __ mtc1(value, STMP1);
2918 __ cvtdw(result, STMP1); 2918 __ cvtdw(result, STMP1);
2919 } else { 2919 } else {
2920 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 2920 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
2921 Label is_smi, done; 2921 Label is_smi, done;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3002 } 3002 }
3003 3003
3004 3004
3005 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 3005 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3006 const intptr_t kNumInputs = 2; 3006 const intptr_t kNumInputs = 2;
3007 const intptr_t kNumTemps = 0; 3007 const intptr_t kNumTemps = 0;
3008 LocationSummary* summary = 3008 LocationSummary* summary =
3009 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3009 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3010 summary->set_in(0, Location::RequiresFpuRegister()); 3010 summary->set_in(0, Location::RequiresFpuRegister());
3011 summary->set_in(1, Location::RequiresFpuRegister()); 3011 summary->set_in(1, Location::RequiresFpuRegister());
3012 summary->set_out(Location::RequiresFpuRegister()); 3012 summary->set_out(0, Location::RequiresFpuRegister());
3013 return summary; 3013 return summary;
3014 } 3014 }
3015 3015
3016 3016
3017 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3017 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3018 DRegister left = locs()->in(0).fpu_reg(); 3018 DRegister left = locs()->in(0).fpu_reg();
3019 DRegister right = locs()->in(1).fpu_reg(); 3019 DRegister right = locs()->in(1).fpu_reg();
3020 DRegister result = locs()->out().fpu_reg(); 3020 DRegister result = locs()->out(0).fpu_reg();
3021 switch (op_kind()) { 3021 switch (op_kind()) {
3022 case Token::kADD: __ addd(result, left, right); break; 3022 case Token::kADD: __ addd(result, left, right); break;
3023 case Token::kSUB: __ subd(result, left, right); break; 3023 case Token::kSUB: __ subd(result, left, right); break;
3024 case Token::kMUL: __ muld(result, left, right); break; 3024 case Token::kMUL: __ muld(result, left, right); break;
3025 case Token::kDIV: __ divd(result, left, right); break; 3025 case Token::kDIV: __ divd(result, left, right); break;
3026 default: UNREACHABLE(); 3026 default: UNREACHABLE();
3027 } 3027 }
3028 } 3028 }
3029 3029
3030 3030
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
3365 3365
3366 3366
3367 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { 3367 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
3368 if ((kind() == MethodRecognizer::kMathSin) || 3368 if ((kind() == MethodRecognizer::kMathSin) ||
3369 (kind() == MethodRecognizer::kMathCos)) { 3369 (kind() == MethodRecognizer::kMathCos)) {
3370 const intptr_t kNumInputs = 1; 3370 const intptr_t kNumInputs = 1;
3371 const intptr_t kNumTemps = 0; 3371 const intptr_t kNumTemps = 0;
3372 LocationSummary* summary = 3372 LocationSummary* summary =
3373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 3373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3374 summary->set_in(0, Location::FpuRegisterLocation(D6)); 3374 summary->set_in(0, Location::FpuRegisterLocation(D6));
3375 summary->set_out(Location::FpuRegisterLocation(D0)); 3375 summary->set_out(0, Location::FpuRegisterLocation(D0));
3376 return summary; 3376 return summary;
3377 } 3377 }
3378 const intptr_t kNumInputs = 1; 3378 const intptr_t kNumInputs = 1;
3379 const intptr_t kNumTemps = 0; 3379 const intptr_t kNumTemps = 0;
3380 LocationSummary* summary = 3380 LocationSummary* summary =
3381 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3381 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3382 summary->set_in(0, Location::RequiresFpuRegister()); 3382 summary->set_in(0, Location::RequiresFpuRegister());
3383 summary->set_out(Location::RequiresFpuRegister()); 3383 summary->set_out(0, Location::RequiresFpuRegister());
3384 return summary; 3384 return summary;
3385 } 3385 }
3386 3386
3387 3387
3388 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3388 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3389 if (kind() == MethodRecognizer::kMathSqrt) { 3389 if (kind() == MethodRecognizer::kMathSqrt) {
3390 __ sqrtd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 3390 __ sqrtd(locs()->out(0).fpu_reg(), locs()->in(0).fpu_reg());
3391 } else { 3391 } else {
3392 __ CallRuntime(TargetFunction(), InputCount()); 3392 __ CallRuntime(TargetFunction(), InputCount());
3393 } 3393 }
3394 } 3394 }
3395 3395
3396 3396
3397 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { 3397 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const {
3398 if (result_cid() == kDoubleCid) { 3398 if (result_cid() == kDoubleCid) {
3399 const intptr_t kNumInputs = 2; 3399 const intptr_t kNumInputs = 2;
3400 const intptr_t kNumTemps = 1; 3400 const intptr_t kNumTemps = 1;
3401 LocationSummary* summary = 3401 LocationSummary* summary =
3402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3403 summary->set_in(0, Location::RequiresFpuRegister()); 3403 summary->set_in(0, Location::RequiresFpuRegister());
3404 summary->set_in(1, Location::RequiresFpuRegister()); 3404 summary->set_in(1, Location::RequiresFpuRegister());
3405 // Reuse the left register so that code can be made shorter. 3405 // Reuse the left register so that code can be made shorter.
3406 summary->set_out(Location::SameAsFirstInput()); 3406 summary->set_out(0, Location::SameAsFirstInput());
3407 summary->set_temp(0, Location::RequiresRegister()); 3407 summary->set_temp(0, Location::RequiresRegister());
3408 return summary; 3408 return summary;
3409 } 3409 }
3410 ASSERT(result_cid() == kSmiCid); 3410 ASSERT(result_cid() == kSmiCid);
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::RequiresRegister()); 3415 summary->set_in(0, Location::RequiresRegister());
3416 summary->set_in(1, Location::RequiresRegister()); 3416 summary->set_in(1, Location::RequiresRegister());
3417 // Reuse the left register so that code can be made shorter. 3417 // Reuse the left register so that code can be made shorter.
3418 summary->set_out(Location::SameAsFirstInput()); 3418 summary->set_out(0, Location::SameAsFirstInput());
3419 return summary; 3419 return summary;
3420 } 3420 }
3421 3421
3422 3422
3423 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3423 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3424 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 3424 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3425 (op_kind() == MethodRecognizer::kMathMax)); 3425 (op_kind() == MethodRecognizer::kMathMax));
3426 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); 3426 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3427 if (result_cid() == kDoubleCid) { 3427 if (result_cid() == kDoubleCid) {
3428 Label done, returns_nan, are_equal; 3428 Label done, returns_nan, are_equal;
3429 DRegister left = locs()->in(0).fpu_reg(); 3429 DRegister left = locs()->in(0).fpu_reg();
3430 DRegister right = locs()->in(1).fpu_reg(); 3430 DRegister right = locs()->in(1).fpu_reg();
3431 DRegister result = locs()->out().fpu_reg(); 3431 DRegister result = locs()->out(0).fpu_reg();
3432 Register temp = locs()->temp(0).reg(); 3432 Register temp = locs()->temp(0).reg();
3433 __ cund(left, right); 3433 __ cund(left, right);
3434 __ bc1t(&returns_nan); 3434 __ bc1t(&returns_nan);
3435 __ ceqd(left, right); 3435 __ ceqd(left, right);
3436 __ bc1t(&are_equal); 3436 __ bc1t(&are_equal);
3437 if (is_min) { 3437 if (is_min) {
3438 __ coltd(left, right); 3438 __ coltd(left, right);
3439 } else { 3439 } else {
3440 __ coltd(right, left); 3440 __ coltd(right, left);
3441 } 3441 }
(...skipping 24 matching lines...) Expand all
3466 } 3466 }
3467 __ movd(result, right); 3467 __ movd(result, right);
3468 __ Bind(&done); 3468 __ Bind(&done);
3469 return; 3469 return;
3470 } 3470 }
3471 3471
3472 Label done; 3472 Label done;
3473 ASSERT(result_cid() == kSmiCid); 3473 ASSERT(result_cid() == kSmiCid);
3474 Register left = locs()->in(0).reg(); 3474 Register left = locs()->in(0).reg();
3475 Register right = locs()->in(1).reg(); 3475 Register right = locs()->in(1).reg();
3476 Register result = locs()->out().reg(); 3476 Register result = locs()->out(0).reg();
3477 ASSERT(result == left); 3477 ASSERT(result == left);
3478 if (is_min) { 3478 if (is_min) {
3479 __ BranchSignedLessEqual(left, right, &done); 3479 __ BranchSignedLessEqual(left, right, &done);
3480 } else { 3480 } else {
3481 __ BranchSignedGreaterEqual(left, right, &done); 3481 __ BranchSignedGreaterEqual(left, right, &done);
3482 } 3482 }
3483 __ mov(result, right); 3483 __ mov(result, right);
3484 __ Bind(&done); 3484 __ Bind(&done);
3485 } 3485 }
3486 3486
3487 3487
3488 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { 3488 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
3489 const intptr_t kNumInputs = 1; 3489 const intptr_t kNumInputs = 1;
3490 const intptr_t kNumTemps = 0; 3490 const intptr_t kNumTemps = 0;
3491 LocationSummary* summary = 3491 LocationSummary* summary =
3492 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3492 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3493 summary->set_in(0, Location::RequiresRegister()); 3493 summary->set_in(0, Location::RequiresRegister());
3494 // We make use of 3-operand instructions by not requiring result register 3494 // We make use of 3-operand instructions by not requiring result register
3495 // to be identical to first input register as on Intel. 3495 // to be identical to first input register as on Intel.
3496 summary->set_out(Location::RequiresRegister()); 3496 summary->set_out(0, Location::RequiresRegister());
3497 return summary; 3497 return summary;
3498 } 3498 }
3499 3499
3500 3500
3501 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3501 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3502 Register value = locs()->in(0).reg(); 3502 Register value = locs()->in(0).reg();
3503 Register result = locs()->out().reg(); 3503 Register result = locs()->out(0).reg();
3504 switch (op_kind()) { 3504 switch (op_kind()) {
3505 case Token::kNEGATE: { 3505 case Token::kNEGATE: {
3506 Label* deopt = compiler->AddDeoptStub(deopt_id(), 3506 Label* deopt = compiler->AddDeoptStub(deopt_id(),
3507 kDeoptUnaryOp); 3507 kDeoptUnaryOp);
3508 __ SubuDetectOverflow(result, ZR, value, CMPRES1); 3508 __ SubuDetectOverflow(result, ZR, value, CMPRES1);
3509 __ bltz(CMPRES1, deopt); 3509 __ bltz(CMPRES1, deopt);
3510 break; 3510 break;
3511 } 3511 }
3512 case Token::kBIT_NOT: 3512 case Token::kBIT_NOT:
3513 __ nor(result, value, ZR); 3513 __ nor(result, value, ZR);
3514 __ addiu(result, result, Immediate(-1)); // Remove inverted smi-tag. 3514 __ addiu(result, result, Immediate(-1)); // Remove inverted smi-tag.
3515 break; 3515 break;
3516 default: 3516 default:
3517 UNREACHABLE(); 3517 UNREACHABLE();
3518 } 3518 }
3519 } 3519 }
3520 3520
3521 3521
3522 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 3522 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3523 const intptr_t kNumInputs = 1; 3523 const intptr_t kNumInputs = 1;
3524 const intptr_t kNumTemps = 1; 3524 const intptr_t kNumTemps = 1;
3525 LocationSummary* summary = 3525 LocationSummary* summary =
3526 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3526 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3527 summary->set_in(0, Location::RequiresFpuRegister()); 3527 summary->set_in(0, Location::RequiresFpuRegister());
3528 summary->set_out(Location::RequiresFpuRegister()); 3528 summary->set_out(0, Location::RequiresFpuRegister());
3529 summary->set_temp(0, Location::RequiresFpuRegister()); 3529 summary->set_temp(0, Location::RequiresFpuRegister());
3530 return summary; 3530 return summary;
3531 } 3531 }
3532 3532
3533 3533
3534 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3534 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3535 // TODO(zra): Implement vneg. 3535 // TODO(zra): Implement vneg.
3536 const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1)); 3536 const Double& minus_one = Double::ZoneHandle(Double::NewCanonical(-1));
3537 __ LoadObject(TMP, minus_one); 3537 __ LoadObject(TMP, minus_one);
3538 FpuRegister result = locs()->out().fpu_reg(); 3538 FpuRegister result = locs()->out(0).fpu_reg();
3539 FpuRegister value = locs()->in(0).fpu_reg(); 3539 FpuRegister value = locs()->in(0).fpu_reg();
3540 FpuRegister temp_fp = locs()->temp(0).fpu_reg(); 3540 FpuRegister temp_fp = locs()->temp(0).fpu_reg();
3541 __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag); 3541 __ LoadDFromOffset(temp_fp, TMP, Double::value_offset() - kHeapObjectTag);
3542 __ muld(result, value, temp_fp); 3542 __ muld(result, value, temp_fp);
3543 } 3543 }
3544 3544
3545 3545
3546 3546
3547 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { 3547 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const {
3548 const intptr_t kNumInputs = 1; 3548 const intptr_t kNumInputs = 1;
3549 const intptr_t kNumTemps = 0; 3549 const intptr_t kNumTemps = 0;
3550 LocationSummary* result = 3550 LocationSummary* result =
3551 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3551 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3552 result->set_in(0, Location::WritableRegister()); 3552 result->set_in(0, Location::WritableRegister());
3553 result->set_out(Location::RequiresFpuRegister()); 3553 result->set_out(0, Location::RequiresFpuRegister());
3554 return result; 3554 return result;
3555 } 3555 }
3556 3556
3557 3557
3558 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3558 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3559 Register value = locs()->in(0).reg(); 3559 Register value = locs()->in(0).reg();
3560 FpuRegister result = locs()->out().fpu_reg(); 3560 FpuRegister result = locs()->out(0).fpu_reg();
3561 __ SmiUntag(value); 3561 __ SmiUntag(value);
3562 __ mtc1(value, STMP1); 3562 __ mtc1(value, STMP1);
3563 __ cvtdw(result, STMP1); 3563 __ cvtdw(result, STMP1);
3564 } 3564 }
3565 3565
3566 3566
3567 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { 3567 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const {
3568 const intptr_t kNumInputs = 1; 3568 const intptr_t kNumInputs = 1;
3569 const intptr_t kNumTemps = 0; 3569 const intptr_t kNumTemps = 0;
3570 LocationSummary* result = 3570 LocationSummary* result =
3571 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 3571 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3572 result->set_in(0, Location::RegisterLocation(T1)); 3572 result->set_in(0, Location::RegisterLocation(T1));
3573 result->set_out(Location::RegisterLocation(V0)); 3573 result->set_out(0, Location::RegisterLocation(V0));
3574 return result; 3574 return result;
3575 } 3575 }
3576 3576
3577 3577
3578 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3578 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3579 Register result = locs()->out().reg(); 3579 Register result = locs()->out(0).reg();
3580 Register value_obj = locs()->in(0).reg(); 3580 Register value_obj = locs()->in(0).reg();
3581 ASSERT(result == V0); 3581 ASSERT(result == V0);
3582 ASSERT(result != value_obj); 3582 ASSERT(result != value_obj);
3583 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); 3583 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag);
3584 __ cvtwd(STMP1, DTMP); 3584 __ cvtwd(STMP1, DTMP);
3585 __ mfc1(result, STMP1); 3585 __ mfc1(result, STMP1);
3586 3586
3587 // Overflow is signaled with minint. 3587 // Overflow is signaled with minint.
3588 Label do_call, done; 3588 Label do_call, done;
3589 // Check for overflow and that it fits into Smi. 3589 // Check for overflow and that it fits into Smi.
(...skipping 19 matching lines...) Expand all
3609 __ Bind(&done); 3609 __ Bind(&done);
3610 } 3610 }
3611 3611
3612 3612
3613 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { 3613 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const {
3614 const intptr_t kNumInputs = 1; 3614 const intptr_t kNumInputs = 1;
3615 const intptr_t kNumTemps = 0; 3615 const intptr_t kNumTemps = 0;
3616 LocationSummary* result = new LocationSummary( 3616 LocationSummary* result = new LocationSummary(
3617 kNumInputs, kNumTemps, LocationSummary::kNoCall); 3617 kNumInputs, kNumTemps, LocationSummary::kNoCall);
3618 result->set_in(0, Location::RequiresFpuRegister()); 3618 result->set_in(0, Location::RequiresFpuRegister());
3619 result->set_out(Location::RequiresRegister()); 3619 result->set_out(0, Location::RequiresRegister());
3620 return result; 3620 return result;
3621 } 3621 }
3622 3622
3623 3623
3624 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3624 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3625 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 3625 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
3626 Register result = locs()->out().reg(); 3626 Register result = locs()->out(0).reg();
3627 DRegister value = locs()->in(0).fpu_reg(); 3627 DRegister value = locs()->in(0).fpu_reg();
3628 __ cvtwd(STMP1, value); 3628 __ cvtwd(STMP1, value);
3629 __ mfc1(result, STMP1); 3629 __ mfc1(result, STMP1);
3630 3630
3631 // Check for overflow and that it fits into Smi. 3631 // Check for overflow and that it fits into Smi.
3632 __ LoadImmediate(TMP, 0xC0000000); 3632 __ LoadImmediate(TMP, 0xC0000000);
3633 __ subu(CMPRES1, result, TMP); 3633 __ subu(CMPRES1, result, TMP);
3634 __ bltz(CMPRES1, deopt); 3634 __ bltz(CMPRES1, deopt);
3635 __ SmiTag(result); 3635 __ SmiTag(result);
3636 } 3636 }
3637 3637
3638 3638
3639 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const { 3639 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(bool opt) const {
3640 UNIMPLEMENTED(); 3640 UNIMPLEMENTED();
3641 return NULL; 3641 return NULL;
3642 } 3642 }
3643 3643
3644 3644
3645 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3645 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3646 UNIMPLEMENTED(); 3646 UNIMPLEMENTED();
3647 } 3647 }
3648 3648
3649 3649
3650 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { 3650 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
3651 const intptr_t kNumInputs = 1; 3651 const intptr_t kNumInputs = 1;
3652 const intptr_t kNumTemps = 0; 3652 const intptr_t kNumTemps = 0;
3653 LocationSummary* result = 3653 LocationSummary* result =
3654 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3654 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3655 result->set_in(0, Location::RequiresFpuRegister()); 3655 result->set_in(0, Location::RequiresFpuRegister());
3656 result->set_out(Location::SameAsFirstInput()); 3656 result->set_out(0, Location::SameAsFirstInput());
3657 return result; 3657 return result;
3658 } 3658 }
3659 3659
3660 3660
3661 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3661 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3662 DRegister value = locs()->in(0).fpu_reg(); 3662 DRegister value = locs()->in(0).fpu_reg();
3663 FRegister result = EvenFRegisterOf(locs()->out().fpu_reg()); 3663 FRegister result = EvenFRegisterOf(locs()->out(0).fpu_reg());
3664 __ cvtsd(result, value); 3664 __ cvtsd(result, value);
3665 } 3665 }
3666 3666
3667 3667
3668 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { 3668 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
3669 const intptr_t kNumInputs = 1; 3669 const intptr_t kNumInputs = 1;
3670 const intptr_t kNumTemps = 0; 3670 const intptr_t kNumTemps = 0;
3671 LocationSummary* result = 3671 LocationSummary* result =
3672 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3672 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3673 result->set_in(0, Location::RequiresFpuRegister()); 3673 result->set_in(0, Location::RequiresFpuRegister());
3674 result->set_out(Location::SameAsFirstInput()); 3674 result->set_out(0, Location::SameAsFirstInput());
3675 return result; 3675 return result;
3676 } 3676 }
3677 3677
3678 3678
3679 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3679 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3680 FRegister value = EvenFRegisterOf(locs()->in(0).fpu_reg()); 3680 FRegister value = EvenFRegisterOf(locs()->in(0).fpu_reg());
3681 DRegister result = locs()->out().fpu_reg(); 3681 DRegister result = locs()->out(0).fpu_reg();
3682 __ cvtds(result, value); 3682 __ cvtds(result, value);
3683 } 3683 }
3684 3684
3685 3685
3686 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 3686 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
3687 // Calling convention on MIPS uses D6 and D7 to pass the first two 3687 // Calling convention on MIPS uses D6 and D7 to pass the first two
3688 // double arguments. 3688 // double arguments.
3689 ASSERT((InputCount() == 1) || (InputCount() == 2)); 3689 ASSERT((InputCount() == 1) || (InputCount() == 2));
3690 const intptr_t kNumTemps = 0; 3690 const intptr_t kNumTemps = 0;
3691 LocationSummary* result = 3691 LocationSummary* result =
3692 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3692 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3693 result->set_in(0, Location::FpuRegisterLocation(D6)); 3693 result->set_in(0, Location::FpuRegisterLocation(D6));
3694 if (InputCount() == 2) { 3694 if (InputCount() == 2) {
3695 result->set_in(1, Location::FpuRegisterLocation(D7)); 3695 result->set_in(1, Location::FpuRegisterLocation(D7));
3696 } 3696 }
3697 result->set_out(Location::FpuRegisterLocation(D0)); 3697 result->set_out(0, Location::FpuRegisterLocation(D0));
3698 return result; 3698 return result;
3699 } 3699 }
3700 3700
3701 3701
3702 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3702 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3703 // For pow-function return NaN if exponent is NaN. 3703 // For pow-function return NaN if exponent is NaN.
3704 Label do_call, skip_call; 3704 Label do_call, skip_call;
3705 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 3705 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
3706 // Pseudo code: 3706 // Pseudo code:
3707 // if (exponent == 0.0) return 0.0; 3707 // if (exponent == 0.0) return 0.0;
3708 // if (base == 1.0) return 1.0; 3708 // if (base == 1.0) return 1.0;
3709 // if (base.isNaN || exponent.isNaN) { 3709 // if (base.isNaN || exponent.isNaN) {
3710 // return double.NAN; 3710 // return double.NAN;
3711 // } 3711 // }
3712 DRegister base = locs()->in(0).fpu_reg(); 3712 DRegister base = locs()->in(0).fpu_reg();
3713 DRegister exp = locs()->in(1).fpu_reg(); 3713 DRegister exp = locs()->in(1).fpu_reg();
3714 DRegister result = locs()->out().fpu_reg(); 3714 DRegister result = locs()->out(0).fpu_reg();
3715 3715
3716 Label check_base_is_one; 3716 Label check_base_is_one;
3717 3717
3718 // Check if exponent is 0.0 -> return 1.0; 3718 // Check if exponent is 0.0 -> return 1.0;
3719 __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(0))); 3719 __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(0)));
3720 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag); 3720 __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag);
3721 __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(1))); 3721 __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(1)));
3722 __ LoadDFromOffset(result, TMP, Double::value_offset() - kHeapObjectTag); 3722 __ LoadDFromOffset(result, TMP, Double::value_offset() - kHeapObjectTag);
3723 // 'result' contains 1.0. 3723 // 'result' contains 1.0.
3724 __ cund(exp, exp); 3724 __ cund(exp, exp);
(...skipping 24 matching lines...) Expand all
3749 if (kind() == MergedMathInstr::kTruncDivMod) { 3749 if (kind() == MergedMathInstr::kTruncDivMod) {
3750 const intptr_t kNumInputs = 2; 3750 const intptr_t kNumInputs = 2;
3751 const intptr_t kNumTemps = 3; 3751 const intptr_t kNumTemps = 3;
3752 LocationSummary* summary = 3752 LocationSummary* summary =
3753 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3753 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3754 summary->set_in(0, Location::RequiresRegister()); 3754 summary->set_in(0, Location::RequiresRegister());
3755 summary->set_in(1, Location::RequiresRegister()); 3755 summary->set_in(1, Location::RequiresRegister());
3756 summary->set_temp(0, Location::RequiresRegister()); 3756 summary->set_temp(0, Location::RequiresRegister());
3757 summary->set_temp(1, Location::RequiresRegister()); // result_div. 3757 summary->set_temp(1, Location::RequiresRegister()); // result_div.
3758 summary->set_temp(2, Location::RequiresRegister()); // result_mod. 3758 summary->set_temp(2, Location::RequiresRegister()); // result_mod.
3759 summary->set_out(Location::RequiresRegister()); 3759 summary->set_out(0, Location::RequiresRegister());
3760 return summary; 3760 return summary;
3761 } 3761 }
3762 UNIMPLEMENTED(); 3762 UNIMPLEMENTED();
3763 return NULL; 3763 return NULL;
3764 } 3764 }
3765 3765
3766 3766
3767 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3767 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3768 Label* deopt = NULL; 3768 Label* deopt = NULL;
3769 if (CanDeoptimize()) { 3769 if (CanDeoptimize()) {
3770 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 3770 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
3771 } 3771 }
3772 if (kind() == MergedMathInstr::kTruncDivMod) { 3772 if (kind() == MergedMathInstr::kTruncDivMod) {
3773 Register left = locs()->in(0).reg(); 3773 Register left = locs()->in(0).reg();
3774 Register right = locs()->in(1).reg(); 3774 Register right = locs()->in(1).reg();
3775 Register result = locs()->out().reg(); 3775 Register result = locs()->out(0).reg();
3776 Register temp = locs()->temp(0).reg(); 3776 Register temp = locs()->temp(0).reg();
3777 Register result_div = locs()->temp(1).reg(); 3777 Register result_div = locs()->temp(1).reg();
3778 Register result_mod = locs()->temp(2).reg(); 3778 Register result_mod = locs()->temp(2).reg();
3779 Range* right_range = InputAt(1)->definition()->range(); 3779 Range* right_range = InputAt(1)->definition()->range();
3780 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 3780 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
3781 // Handle divide by zero in runtime. 3781 // Handle divide by zero in runtime.
3782 __ beq(right, ZR, deopt); 3782 __ beq(right, ZR, deopt);
3783 } 3783 }
3784 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp. 3784 __ sra(temp, left, kSmiTagSize); // SmiUntag left into temp.
3785 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 3785 __ sra(TMP, right, kSmiTagSize); // SmiUntag right into TMP.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
3873 deopt, 3873 deopt,
3874 deopt_id(), 3874 deopt_id(),
3875 instance_call()->token_pos(), 3875 instance_call()->token_pos(),
3876 locs()); 3876 locs());
3877 } 3877 }
3878 3878
3879 3879
3880 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { 3880 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
3881 comparison()->InitializeLocationSummary(opt); 3881 comparison()->InitializeLocationSummary(opt);
3882 // Branches don't produce a result. 3882 // Branches don't produce a result.
3883 comparison()->locs()->set_out(Location::NoLocation()); 3883 comparison()->locs()->set_out(0, Location::NoLocation());
3884 return comparison()->locs(); 3884 return comparison()->locs();
3885 } 3885 }
3886 3886
3887 3887
3888 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3888 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3889 __ TraceSimMsg("BranchInstr"); 3889 __ TraceSimMsg("BranchInstr");
3890 comparison()->EmitBranchCode(compiler, this); 3890 comparison()->EmitBranchCode(compiler, this);
3891 } 3891 }
3892 3892
3893 3893
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4159 4159
4160 4160
4161 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { 4161 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
4162 return LocationSummary::Make(0, 4162 return LocationSummary::Make(0,
4163 Location::RequiresRegister(), 4163 Location::RequiresRegister(),
4164 LocationSummary::kNoCall); 4164 LocationSummary::kNoCall);
4165 } 4165 }
4166 4166
4167 4167
4168 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4168 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4169 __ mov(locs()->out().reg(), CTX); 4169 __ mov(locs()->out(0).reg(), CTX);
4170 } 4170 }
4171 4171
4172 4172
4173 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { 4173 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
4174 const intptr_t kNumInputs = 2; 4174 const intptr_t kNumInputs = 2;
4175 const intptr_t kNumTemps = 0; 4175 const intptr_t kNumTemps = 0;
4176 if (needs_number_check()) { 4176 if (needs_number_check()) {
4177 LocationSummary* locs = 4177 LocationSummary* locs =
4178 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4178 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4179 locs->set_in(0, Location::RegisterLocation(A0)); 4179 locs->set_in(0, Location::RegisterLocation(A0));
4180 locs->set_in(1, Location::RegisterLocation(A1)); 4180 locs->set_in(1, Location::RegisterLocation(A1));
4181 locs->set_out(Location::RegisterLocation(A0)); 4181 locs->set_out(0, Location::RegisterLocation(A0));
4182 return locs; 4182 return locs;
4183 } 4183 }
4184 LocationSummary* locs = 4184 LocationSummary* locs =
4185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4186 locs->set_in(0, Location::RegisterOrConstant(left())); 4186 locs->set_in(0, Location::RegisterOrConstant(left()));
4187 // Only one of the inputs can be a constant. Choose register if the first one 4187 // Only one of the inputs can be a constant. Choose register if the first one
4188 // is a constant. 4188 // is a constant.
4189 locs->set_in(1, locs->in(0).IsConstant() 4189 locs->set_in(1, locs->in(0).IsConstant()
4190 ? Location::RequiresRegister() 4190 ? Location::RequiresRegister()
4191 : Location::RegisterOrConstant(right())); 4191 : Location::RegisterOrConstant(right()));
4192 locs->set_out(Location::RequiresRegister()); 4192 locs->set_out(0, Location::RequiresRegister());
4193 return locs; 4193 return locs;
4194 } 4194 }
4195 4195
4196 4196
4197 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 4197 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
4198 BranchLabels labels) { 4198 BranchLabels labels) {
4199 Location left = locs()->in(0); 4199 Location left = locs()->in(0);
4200 Location right = locs()->in(1); 4200 Location right = locs()->in(1);
4201 ASSERT(!left.IsConstant() || !right.IsConstant()); 4201 ASSERT(!left.IsConstant() || !right.IsConstant());
4202 if (left.IsConstant()) { 4202 if (left.IsConstant()) {
(...skipping 20 matching lines...) Expand all
4223 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4223 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4224 __ TraceSimMsg("StrictCompareInstr"); 4224 __ TraceSimMsg("StrictCompareInstr");
4225 __ Comment("StrictCompareInstr"); 4225 __ Comment("StrictCompareInstr");
4226 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4226 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4227 4227
4228 Label is_true, is_false; 4228 Label is_true, is_false;
4229 BranchLabels labels = { &is_true, &is_false, &is_false }; 4229 BranchLabels labels = { &is_true, &is_false, &is_false };
4230 Condition true_condition = EmitComparisonCode(compiler, labels); 4230 Condition true_condition = EmitComparisonCode(compiler, labels);
4231 EmitBranchOnCondition(compiler, true_condition, labels); 4231 EmitBranchOnCondition(compiler, true_condition, labels);
4232 4232
4233 Register result = locs()->out().reg(); 4233 Register result = locs()->out(0).reg();
4234 Label done; 4234 Label done;
4235 __ Bind(&is_false); 4235 __ Bind(&is_false);
4236 __ LoadObject(result, Bool::False()); 4236 __ LoadObject(result, Bool::False());
4237 __ b(&done); 4237 __ b(&done);
4238 __ Bind(&is_true); 4238 __ Bind(&is_true);
4239 __ LoadObject(result, Bool::True()); 4239 __ LoadObject(result, Bool::True());
4240 __ Bind(&done); 4240 __ Bind(&done);
4241 } 4241 }
4242 4242
4243 4243
(...skipping 10 matching lines...) Expand all
4254 4254
4255 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { 4255 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
4256 return LocationSummary::Make(1, 4256 return LocationSummary::Make(1,
4257 Location::RequiresRegister(), 4257 Location::RequiresRegister(),
4258 LocationSummary::kNoCall); 4258 LocationSummary::kNoCall);
4259 } 4259 }
4260 4260
4261 4261
4262 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4262 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4263 Register value = locs()->in(0).reg(); 4263 Register value = locs()->in(0).reg();
4264 Register result = locs()->out().reg(); 4264 Register result = locs()->out(0).reg();
4265 4265
4266 __ LoadObject(result, Bool::True()); 4266 __ LoadObject(result, Bool::True());
4267 __ LoadObject(TMP, Bool::False()); 4267 __ LoadObject(TMP, Bool::False());
4268 __ subu(CMPRES1, value, result); 4268 __ subu(CMPRES1, value, result);
4269 __ movz(result, TMP, CMPRES1); // If value is True, move False into result. 4269 __ movz(result, TMP, CMPRES1); // If value is True, move False into result.
4270 } 4270 }
4271 4271
4272 4272
4273 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { 4273 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const {
4274 return MakeCallSummary(); 4274 return MakeCallSummary();
4275 } 4275 }
4276 4276
4277 4277
4278 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4278 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4279 __ TraceSimMsg("AllocateObjectInstr"); 4279 __ TraceSimMsg("AllocateObjectInstr");
4280 __ Comment("AllocateObjectInstr"); 4280 __ Comment("AllocateObjectInstr");
4281 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); 4281 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls()));
4282 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); 4282 const ExternalLabel label(cls().ToCString(), stub.EntryPoint());
4283 compiler->GenerateCall(token_pos(), 4283 compiler->GenerateCall(token_pos(),
4284 &label, 4284 &label,
4285 PcDescriptors::kOther, 4285 PcDescriptors::kOther,
4286 locs()); 4286 locs());
4287 __ Drop(ArgumentCount()); // Discard arguments. 4287 __ Drop(ArgumentCount()); // Discard arguments.
4288 } 4288 }
4289 4289
4290 } // namespace dart 4290 } // namespace dart
4291 4291
4292 #endif // defined TARGET_ARCH_MIPS 4292 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698