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

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

Issue 10458050: Move ReturnInstr to new scheme (x64 and ia32) and implement more code in new ia32 compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "lib/error.h" 8 #include "lib/error.h"
9 #include "vm/flow_graph_compiler.h" 9 #include "vm/flow_graph_compiler.h"
10 #include "vm/locations.h" 10 #include "vm/locations.h"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 #include "vm/stub_code.h" 13 #include "vm/stub_code.h"
14 14
15 #define __ compiler->assembler()-> 15 #define __ compiler->assembler()->
16 16
17 namespace dart { 17 namespace dart {
18 18
19 19 DECLARE_FLAG(bool, optimization_counter_threshold);
20 static LocationSummary* MakeSimpleLocationSummary( 20 DECLARE_FLAG(bool, trace_functions);
21 intptr_t input_count, Location out) {
22 LocationSummary* summary = new LocationSummary(input_count, 0);
23 for (intptr_t i = 0; i < input_count; i++) {
24 summary->set_in(i, Location::RequiresRegister());
25 }
26 summary->set_out(out);
27 return summary;
28 }
29 21
30 22
31 // True iff. the arguments to a call will be properly pushed and can 23 // True iff. the arguments to a call will be properly pushed and can
32 // be popped after the call. 24 // be popped after the call.
33 template <typename T> static bool VerifyCallComputation(T* comp) { 25 template <typename T> static bool VerifyCallComputation(T* comp) {
34 // Argument values should be consecutive temps. 26 // Argument values should be consecutive temps.
35 // 27 //
36 // TODO(kmillikin): implement stack height tracking so we can also assert 28 // TODO(kmillikin): implement stack height tracking so we can also assert
37 // they are on top of the stack. 29 // they are on top of the stack.
38 intptr_t previous = -1; 30 intptr_t previous = -1;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 // comparison with true fails. 111 // comparison with true fails.
120 __ j(EQUAL, compiler->GetBlockLabel(true_successor())); 112 __ j(EQUAL, compiler->GetBlockLabel(true_successor()));
121 } else { 113 } else {
122 // If the next block is the true sucessor we negate comparison and fall 114 // If the next block is the true sucessor we negate comparison and fall
123 // through to it. 115 // through to it.
124 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor())); 116 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor()));
125 } 117 }
126 } 118 }
127 119
128 120
121 LocationSummary* ReturnInstr::MakeLocationSummary() const {
122 const intptr_t kNumInputs = 1;
123 const intptr_t kNumTemps = 1;
124 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
125 locs->set_in(0, Location::RegisterLocation(RAX));
126 locs->set_temp(0, Location::RequiresRegister());
127 return locs;
128 }
129
130
131 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
132 Register result = locs()->in(0).reg();
133 Register temp = locs()->temp(0).reg();
134 ASSERT(result == RAX);
135 if (!compiler->is_optimizing()) {
136 // Count only in unoptimized code.
137 // TODO(srdjan): Replace the counting code with a type feedback
138 // collection and counting stub.
139 const Function& function =
140 Function::ZoneHandle(compiler->parsed_function().function().raw());
141 __ LoadObject(temp, function);
142 __ incq(FieldAddress(temp, Function::usage_counter_offset()));
143 if (CodeGenerator::CanOptimize()) {
144 // Do not optimize if usage count must be reported.
145 __ cmpl(FieldAddress(temp, Function::usage_counter_offset()),
146 Immediate(FLAG_optimization_counter_threshold));
147 Label not_yet_hot;
148 __ j(LESS_EQUAL, &not_yet_hot, Assembler::kNearJump);
149 __ pushq(result); // Preserve result.
150 __ pushq(temp); // Argument for runtime: function to optimize.
151 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
152 __ popq(temp); // Remove argument.
153 __ popq(result); // Restore result.
154 __ Bind(&not_yet_hot);
155 }
156 }
157 if (FLAG_trace_functions) {
158 __ pushq(result); // Preserve result.
159 const Function& function =
160 Function::ZoneHandle(compiler->parsed_function().function().raw());
161 __ LoadObject(temp, function);
162 __ pushq(temp);
163 compiler->GenerateCallRuntime(AstNode::kNoId,
164 0,
165 CatchClauseNode::kInvalidTryIndex,
166 kTraceFunctionExitRuntimeEntry);
167 __ popq(temp); // Remove argument.
168 __ popq(result); // Restore result.
169 }
170 __ LeaveFrame();
171 __ ret();
172
173 // Generate 8 bytes of NOPs so that the debugger can patch the
174 // return pattern with a call to the debug stub.
175 __ nop(1);
176 __ nop(1);
177 __ nop(1);
178 __ nop(1);
179 __ nop(1);
180 __ nop(1);
181 __ nop(1);
182 __ nop(1);
183 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
184 cid(),
185 token_index(),
186 CatchClauseNode::kInvalidTryIndex);
187 }
188
189
129 LocationSummary* CurrentContextComp::MakeLocationSummary() const { 190 LocationSummary* CurrentContextComp::MakeLocationSummary() const {
130 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); 191 return LocationSummary::Make(0, Location::RequiresRegister());
131 } 192 }
132 193
133 194
134 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 195 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
135 __ movq(locs()->out().reg(), CTX); 196 __ movq(locs()->out().reg(), CTX);
136 } 197 }
137 198
138 199
139 LocationSummary* StoreContextComp::MakeLocationSummary() const { 200 LocationSummary* StoreContextComp::MakeLocationSummary() const {
140 LocationSummary* summary = new LocationSummary(1, 0); 201 LocationSummary* summary = new LocationSummary(1, 0);
141 summary->set_in(0, Location::RegisterLocation(CTX)); 202 summary->set_in(0, Location::RegisterLocation(CTX));
142 return summary; 203 return summary;
143 } 204 }
144 205
145 206
146 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 207 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
147 // Nothing to do. Context register were loaded by register allocator. 208 // Nothing to do. Context register were loaded by register allocator.
148 ASSERT(locs()->in(0).reg() == CTX); 209 ASSERT(locs()->in(0).reg() == CTX);
149 } 210 }
150 211
151 212
152 LocationSummary* StrictCompareComp::MakeLocationSummary() const { 213 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
153 return MakeSimpleLocationSummary(2, Location::SameAsFirstInput()); 214 return LocationSummary::Make(2, Location::SameAsFirstInput());
154 } 215 }
155 216
156 217
157 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 218 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
158 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 219 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
159 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 220 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
160 221
161 Register left = locs()->in(0).reg(); 222 Register left = locs()->in(0).reg();
162 Register right = locs()->in(1).reg(); 223 Register right = locs()->in(1).reg();
163 Register result = locs()->out().reg(); 224 Register result = locs()->out().reg();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 ASSERT(VerifyCallComputation(this)); 301 ASSERT(VerifyCallComputation(this));
241 compiler->EmitStaticCall(token_index(), 302 compiler->EmitStaticCall(token_index(),
242 try_index(), 303 try_index(),
243 function(), 304 function(),
244 ArgumentCount(), 305 ArgumentCount(),
245 argument_names()); 306 argument_names());
246 } 307 }
247 308
248 309
249 LocationSummary* LoadLocalComp::MakeLocationSummary() const { 310 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
250 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); 311 return LocationSummary::Make(0, Location::RequiresRegister());
251 } 312 }
252 313
253 314
254 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 315 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
255 Register result = locs()->out().reg(); 316 Register result = locs()->out().reg();
256 __ movq(result, Address(RBP, local().index() * kWordSize)); 317 __ movq(result, Address(RBP, local().index() * kWordSize));
257 } 318 }
258 319
259 320
260 LocationSummary* StoreLocalComp::MakeLocationSummary() const { 321 LocationSummary* StoreLocalComp::MakeLocationSummary() const {
261 return MakeSimpleLocationSummary(1, Location::SameAsFirstInput()); 322 return LocationSummary::Make(1, Location::SameAsFirstInput());
262 } 323 }
263 324
264 325
265 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 326 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
266 Register value = locs()->in(0).reg(); 327 Register value = locs()->in(0).reg();
267 Register result = locs()->out().reg(); 328 Register result = locs()->out().reg();
268 ASSERT(result == value); // Assert that register assignment is correct. 329 ASSERT(result == value); // Assert that register assignment is correct.
269 __ movq(Address(RBP, local().index() * kWordSize), value); 330 __ movq(Address(RBP, local().index() * kWordSize), value);
270 } 331 }
271 332
272 333
273 LocationSummary* ConstantVal::MakeLocationSummary() const { 334 LocationSummary* ConstantVal::MakeLocationSummary() const {
274 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); 335 return LocationSummary::Make(0, Location::RequiresRegister());
275 } 336 }
276 337
277 338
278 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { 339 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) {
279 Register result = locs()->out().reg(); 340 Register result = locs()->out().reg();
280 if (value().IsSmi()) { 341 if (value().IsSmi()) {
281 int64_t imm = reinterpret_cast<int64_t>(value().raw()); 342 int64_t imm = reinterpret_cast<int64_t>(value().raw());
282 __ movq(result, Immediate(imm)); 343 __ movq(result, Immediate(imm));
283 } else { 344 } else {
284 __ LoadObject(result, value()); 345 __ LoadObject(result, value());
(...skipping 29 matching lines...) Expand all
314 compiler->GenerateAssertAssignable(cid(), 375 compiler->GenerateAssertAssignable(cid(),
315 token_index(), 376 token_index(),
316 try_index(), 377 try_index(),
317 dst_type(), 378 dst_type(),
318 dst_name()); 379 dst_name());
319 ASSERT(locs()->in(0).reg() == locs()->out().reg()); 380 ASSERT(locs()->in(0).reg() == locs()->out().reg());
320 } 381 }
321 382
322 383
323 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { 384 LocationSummary* AssertBooleanComp::MakeLocationSummary() const {
324 return MakeSimpleLocationSummary(1, Location::SameAsFirstInput()); 385 return LocationSummary::Make(1, Location::SameAsFirstInput());
325 } 386 }
326 387
327 388
328 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { 389 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) {
329 Register obj = locs()->in(0).reg(); 390 Register obj = locs()->in(0).reg();
330 Register result = locs()->out().reg(); 391 Register result = locs()->out().reg();
331 392
332 // Check that the type of the value is allowed in conditional context. 393 // Check that the type of the value is allowed in conditional context.
333 // Call the runtime if the object is not bool::true or bool::false. 394 // Call the runtime if the object is not bool::true or bool::false.
334 Label done; 395 Label done;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 kNumArgumentsChecked); 461 kNumArgumentsChecked);
401 __ Bind(&done); 462 __ Bind(&done);
402 } 463 }
403 464
404 465
405 LocationSummary* NativeCallComp::MakeLocationSummary() const { 466 LocationSummary* NativeCallComp::MakeLocationSummary() const {
406 LocationSummary* locs = new LocationSummary(0, 3); 467 LocationSummary* locs = new LocationSummary(0, 3);
407 locs->set_temp(0, Location::RegisterLocation(RAX)); 468 locs->set_temp(0, Location::RegisterLocation(RAX));
408 locs->set_temp(1, Location::RegisterLocation(RBX)); 469 locs->set_temp(1, Location::RegisterLocation(RBX));
409 locs->set_temp(2, Location::RegisterLocation(R10)); 470 locs->set_temp(2, Location::RegisterLocation(R10));
410 locs->set_out(Location::RegisterLocation(RAX)); 471 locs->set_out(Location::RequiresRegister());
411 return locs; 472 return locs;
412 } 473 }
413 474
414 475
415 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 476 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
416 ASSERT(locs()->temp(0).reg() == RAX); 477 ASSERT(locs()->temp(0).reg() == RAX);
417 ASSERT(locs()->temp(1).reg() == RBX); 478 ASSERT(locs()->temp(1).reg() == RBX);
418 ASSERT(locs()->temp(2).reg() == R10); 479 ASSERT(locs()->temp(2).reg() == R10);
419 ASSERT(locs()->out().reg() == RAX); 480 Register result = locs()->out().reg();
420 481
421 // Push the result place holder initialized to NULL. 482 // Push the result place holder initialized to NULL.
422 __ PushObject(Object::ZoneHandle()); 483 __ PushObject(Object::ZoneHandle());
423 // Pass a pointer to the first argument in RAX. 484 // Pass a pointer to the first argument in RAX.
424 if (!has_optional_parameters()) { 485 if (!has_optional_parameters()) {
425 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); 486 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize));
426 } else { 487 } else {
427 __ leaq(RAX, 488 __ leaq(RAX,
428 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 489 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
429 } 490 }
430 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); 491 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
431 __ movq(R10, Immediate(argument_count())); 492 __ movq(R10, Immediate(argument_count()));
432 compiler->GenerateCall(token_index(), 493 compiler->GenerateCall(token_index(),
433 try_index(), 494 try_index(),
434 &StubCode::CallNativeCFunctionLabel(), 495 &StubCode::CallNativeCFunctionLabel(),
435 PcDescriptors::kOther); 496 PcDescriptors::kOther);
436 __ popq(RAX); 497 __ popq(result);
437 } 498 }
438 499
439 500
440 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { 501 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
441 const intptr_t kNumInputs = 3; 502 const intptr_t kNumInputs = 3;
442 return MakeSimpleLocationSummary(kNumInputs, Location::NoLocation()); 503 return LocationSummary::Make(kNumInputs, Location::NoLocation());
443 } 504 }
444 505
445 506
446 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 507 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
447 Register receiver = locs()->in(0).reg(); 508 Register receiver = locs()->in(0).reg();
448 Register index = locs()->in(1).reg(); 509 Register index = locs()->in(1).reg();
449 Register value = locs()->in(2).reg(); 510 Register value = locs()->in(2).reg();
450 511
451 const String& function_name = 512 const String& function_name =
452 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 513 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
453 514
454 __ pushq(receiver); 515 __ pushq(receiver);
455 __ pushq(index); 516 __ pushq(index);
456 __ pushq(value); 517 __ pushq(value);
457 const intptr_t kNumArguments = 3; 518 const intptr_t kNumArguments = 3;
458 const intptr_t kNumArgsChecked = 1; // Type-feedback. 519 const intptr_t kNumArgsChecked = 1; // Type-feedback.
459 compiler->EmitInstanceCall(cid(), 520 compiler->EmitInstanceCall(cid(),
460 token_index(), 521 token_index(),
461 try_index(), 522 try_index(),
462 function_name, 523 function_name,
463 kNumArguments, 524 kNumArguments,
464 Array::ZoneHandle(), // No optional arguments. 525 Array::ZoneHandle(), // No optional arguments.
465 kNumArgsChecked); 526 kNumArgsChecked);
466 } 527 }
467 528
468 529
469 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { 530 LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
470 const intptr_t kNumInputs = 2; 531 const intptr_t kNumInputs = 2;
471 return MakeSimpleLocationSummary(kNumInputs, Location::RequiresRegister()); 532 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
472 return NULL; 533 return NULL;
473 } 534 }
474 535
475 536
476 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 537 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
477 Register receiver = locs()->in(0).reg(); 538 Register receiver = locs()->in(0).reg();
478 Register value = locs()->in(1).reg(); 539 Register value = locs()->in(1).reg();
479 Register result = locs()->out().reg(); 540 Register result = locs()->out().reg();
480 541
481 // Preserve the value (second argument) under the arguments as the result 542 // Preserve the value (second argument) under the arguments as the result
(...skipping 12 matching lines...) Expand all
494 function_name, 555 function_name,
495 2, 556 2,
496 Array::ZoneHandle(), 557 Array::ZoneHandle(),
497 1); 558 1);
498 __ popq(result); 559 __ popq(result);
499 } 560 }
500 561
501 562
502 LocationSummary* StaticSetterComp::MakeLocationSummary() const { 563 LocationSummary* StaticSetterComp::MakeLocationSummary() const {
503 const intptr_t kNumInputs = 1; 564 const intptr_t kNumInputs = 1;
504 return MakeSimpleLocationSummary(kNumInputs, Location::RequiresRegister()); 565 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
505 } 566 }
506 567
507 568
508 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 569 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
509 Register value = locs()->in(0).reg(); 570 Register value = locs()->in(0).reg();
510 Register result = locs()->out().reg(); 571 Register result = locs()->out().reg();
511 572
512 // Preserve the argument as the result of the computation, 573 // Preserve the argument as the result of the computation,
513 // then call the setter. 574 // then call the setter.
514 575
515 // Duplicate the argument. 576 // Duplicate the argument.
516 // TODO(fschneider): Avoid preserving the value if the result is not used. 577 // TODO(fschneider): Avoid preserving the value if the result is not used.
517 __ pushq(value); 578 __ pushq(value);
518 __ pushq(value); 579 __ pushq(value);
519 compiler->EmitStaticCall(token_index(), 580 compiler->EmitStaticCall(token_index(),
520 try_index(), 581 try_index(),
521 setter_function(), 582 setter_function(),
522 1, 583 1,
523 Array::ZoneHandle()); 584 Array::ZoneHandle());
524 __ popq(result); 585 __ popq(result);
525 } 586 }
526 587
527 588
528 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { 589 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
529 // TODO(fschneider): For this instruction the input register may be 590 // TODO(fschneider): For this instruction the input register may be
530 // reused for the result (but is not required to) because the input 591 // reused for the result (but is not required to) because the input
531 // is not used after the result is defined. We should consider adding 592 // is not used after the result is defined. We should consider adding
532 // this information to the input policy. 593 // this information to the input policy.
533 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); 594 return LocationSummary::Make(1, Location::RequiresRegister());
534 } 595 }
535 596
536 597
537 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 598 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
538 Register instance = locs()->in(0).reg(); 599 Register instance = locs()->in(0).reg();
539 Register result = locs()->out().reg(); 600 Register result = locs()->out().reg();
540 601
541 __ movq(result, FieldAddress(instance, field().Offset())); 602 __ movq(result, FieldAddress(instance, field().Offset()));
542 } 603 }
543 604
544 605
545 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { 606 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const {
546 return MakeSimpleLocationSummary(2, Location::RequiresRegister()); 607 return LocationSummary::Make(2, Location::RequiresRegister());
547 } 608 }
548 609
549 610
550 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 611 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
551 ASSERT(VerifyValues(instance(), value())); 612 ASSERT(VerifyValues(instance(), value()));
552 Register instance = locs()->in(0).reg(); 613 Register instance = locs()->in(0).reg();
553 Register value = locs()->in(1).reg(); 614 Register value = locs()->in(1).reg();
554 Register result = locs()->out().reg(); 615 Register result = locs()->out().reg();
555 616
556 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), 617 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()),
557 value); 618 value);
558 // TODO(fschneider): Consider eliminating this move by specifying a 619 // TODO(fschneider): Consider eliminating this move by specifying a
559 // SameAsSecondInput for the result. 620 // SameAsSecondInput for the result.
560 if (result != value) { 621 if (result != value) {
561 __ movq(result, value); 622 __ movq(result, value);
562 } 623 }
563 } 624 }
564 625
565 626
566 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { 627 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
567 return MakeSimpleLocationSummary(0, Location::RequiresRegister()); 628 return LocationSummary::Make(0, Location::RequiresRegister());
568 } 629 }
569 630
570 631
571 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 632 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
572 Register result = locs()->out().reg(); 633 Register result = locs()->out().reg();
573 __ LoadObject(result, field()); 634 __ LoadObject(result, field());
574 __ movq(result, FieldAddress(result, Field::value_offset())); 635 __ movq(result, FieldAddress(result, Field::value_offset()));
575 } 636 }
576 637
577 638
(...skipping 10 matching lines...) Expand all
588 Register value = locs()->in(0).reg(); 649 Register value = locs()->in(0).reg();
589 Register temp = locs()->temp(0).reg(); 650 Register temp = locs()->temp(0).reg();
590 ASSERT(locs()->out().reg() == value); 651 ASSERT(locs()->out().reg() == value);
591 652
592 __ LoadObject(temp, field()); 653 __ LoadObject(temp, field());
593 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); 654 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
594 } 655 }
595 656
596 657
597 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { 658 LocationSummary* BooleanNegateComp::MakeLocationSummary() const {
598 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); 659 return LocationSummary::Make(1, Location::RequiresRegister());
599 } 660 }
600 661
601 662
602 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { 663 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
603 Register value = locs()->in(0).reg(); 664 Register value = locs()->in(0).reg();
604 Register result = locs()->out().reg(); 665 Register result = locs()->out().reg();
605 666
606 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 667 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
607 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 668 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
608 Label done; 669 Label done;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 compiler->GenerateCall(token_index(), 764 compiler->GenerateCall(token_index(),
704 try_index(), 765 try_index(),
705 &label, 766 &label,
706 PcDescriptors::kOther); 767 PcDescriptors::kOther);
707 __ Drop(arguments().length()); // Discard arguments. 768 __ Drop(arguments().length()); // Discard arguments.
708 } 769 }
709 770
710 771
711 LocationSummary* AllocateObjectWithBoundsCheckComp:: 772 LocationSummary* AllocateObjectWithBoundsCheckComp::
712 MakeLocationSummary() const { 773 MakeLocationSummary() const {
713 return MakeSimpleLocationSummary(2, Location::RequiresRegister()); 774 return LocationSummary::Make(2, Location::RequiresRegister());
714 } 775 }
715 776
716 777
717 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 778 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
718 FlowGraphCompiler* compiler) { 779 FlowGraphCompiler* compiler) {
719 const Class& cls = Class::ZoneHandle(constructor().owner()); 780 const Class& cls = Class::ZoneHandle(constructor().owner());
720 Register type_arguments = locs()->in(0).reg(); 781 Register type_arguments = locs()->in(0).reg();
721 Register instantiator_type_arguments = locs()->in(1).reg(); 782 Register instantiator_type_arguments = locs()->in(1).reg();
722 Register result = locs()->out().reg(); 783 Register result = locs()->out().reg();
723 784
724 // Push the result place holder initialized to NULL. 785 // Push the result place holder initialized to NULL.
725 __ PushObject(Object::ZoneHandle()); 786 __ PushObject(Object::ZoneHandle());
726 __ pushq(Immediate(Smi::RawValue(token_index()))); 787 __ pushq(Immediate(Smi::RawValue(token_index())));
727 __ PushObject(cls); 788 __ PushObject(cls);
728 __ pushq(type_arguments); 789 __ pushq(type_arguments);
729 __ pushq(instantiator_type_arguments); 790 __ pushq(instantiator_type_arguments);
730 compiler->GenerateCallRuntime(cid(), 791 compiler->GenerateCallRuntime(cid(),
731 token_index(), 792 token_index(),
732 try_index(), 793 try_index(),
733 kAllocateObjectWithBoundsCheckRuntimeEntry); 794 kAllocateObjectWithBoundsCheckRuntimeEntry);
734 // Pop instantiator type arguments, type arguments, class, and 795 // Pop instantiator type arguments, type arguments, class, and
735 // source location. 796 // source location.
736 __ Drop(4); 797 __ Drop(4);
737 __ popq(result); // Pop new instance. 798 __ popq(result); // Pop new instance.
738 } 799 }
739 800
740 801
741 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 802 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
742 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); 803 return LocationSummary::Make(1, Location::RequiresRegister());
743 } 804 }
744 805
745 806
746 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 807 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
747 Register obj = locs()->in(0).reg(); 808 Register obj = locs()->in(0).reg();
748 Register result = locs()->out().reg(); 809 Register result = locs()->out().reg();
749 810
750 __ movq(result, FieldAddress(obj, offset_in_bytes())); 811 __ movq(result, FieldAddress(obj, offset_in_bytes()));
751 } 812 }
752 813
753 814
754 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const { 815 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const {
755 return MakeSimpleLocationSummary(2, Location::SameAsFirstInput()); 816 return LocationSummary::Make(2, Location::SameAsFirstInput());
756 } 817 }
757 818
758 819
759 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 820 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
760 Register value_reg = locs()->in(0).reg(); 821 Register value_reg = locs()->in(0).reg();
761 Register dest_reg = locs()->in(1).reg(); 822 Register dest_reg = locs()->in(1).reg();
762 ASSERT(value_reg == locs()->out().reg()); 823 ASSERT(value_reg == locs()->out().reg());
763 824
764 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 825 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
765 value_reg); 826 value_reg);
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 const ExternalLabel label("alloc_context", 1024 const ExternalLabel label("alloc_context",
964 StubCode::AllocateContextEntryPoint()); 1025 StubCode::AllocateContextEntryPoint());
965 compiler->GenerateCall(token_index(), 1026 compiler->GenerateCall(token_index(),
966 try_index(), 1027 try_index(),
967 &label, 1028 &label,
968 PcDescriptors::kOther); 1029 PcDescriptors::kOther);
969 } 1030 }
970 1031
971 1032
972 LocationSummary* ChainContextComp::MakeLocationSummary() const { 1033 LocationSummary* ChainContextComp::MakeLocationSummary() const {
973 return MakeSimpleLocationSummary(1, Location::NoLocation()); 1034 return LocationSummary::Make(1, Location::NoLocation());
974 } 1035 }
975 1036
976 1037
977 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1038 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
978 Register context_value = locs()->in(0).reg(); 1039 Register context_value = locs()->in(0).reg();
979 1040
980 // Chain the new context in context_value to its parent in CTX. 1041 // Chain the new context in context_value to its parent in CTX.
981 __ StoreIntoObject(context_value, 1042 __ StoreIntoObject(context_value,
982 FieldAddress(context_value, Context::parent_offset()), 1043 FieldAddress(context_value, Context::parent_offset()),
983 CTX); 1044 CTX);
984 // Set new context as current context. 1045 // Set new context as current context.
985 __ movq(CTX, context_value); 1046 __ movq(CTX, context_value);
986 } 1047 }
987 1048
988 1049
989 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1050 LocationSummary* CloneContextComp::MakeLocationSummary() const {
990 return MakeSimpleLocationSummary(1, Location::RequiresRegister()); 1051 return LocationSummary::Make(1, Location::RequiresRegister());
991 } 1052 }
992 1053
993 1054
994 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1055 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
995 Register context_value = locs()->in(0).reg(); 1056 Register context_value = locs()->in(0).reg();
996 Register result = locs()->out().reg(); 1057 Register result = locs()->out().reg();
997 1058
998 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1059 __ PushObject(Object::ZoneHandle()); // Make room for the result.
999 __ pushq(context_value); 1060 __ pushq(context_value);
1000 compiler->GenerateCallRuntime(cid(), 1061 compiler->GenerateCallRuntime(cid(),
1001 token_index(), 1062 token_index(),
1002 try_index(), 1063 try_index(),
1003 kCloneContextRuntimeEntry); 1064 kCloneContextRuntimeEntry);
1004 __ popq(result); // Remove argument. 1065 __ popq(result); // Remove argument.
1005 __ popq(result); // Get result (cloned context). 1066 __ popq(result); // Get result (cloned context).
1006 } 1067 }
1007 1068
1008 1069
1009 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1070 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1010 return MakeSimpleLocationSummary(0, Location::NoLocation()); 1071 return LocationSummary::Make(0, Location::NoLocation());
1011 } 1072 }
1012 1073
1013 1074
1014 // Restore stack and initialize the two exception variables: 1075 // Restore stack and initialize the two exception variables:
1015 // exception and stack trace variables. 1076 // exception and stack trace variables.
1016 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1077 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1017 // Restore RSP from RBP as we are coming from a throw and the code for 1078 // Restore RSP from RBP as we are coming from a throw and the code for
1018 // popping arguments has not been run. 1079 // popping arguments has not been run.
1019 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; 1080 const intptr_t locals_space_size = compiler->StackSize() * kWordSize;
1020 ASSERT(locals_space_size >= 0); 1081 ASSERT(locals_space_size >= 0);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 if (locs()->out().reg() != RAX) { 1296 if (locs()->out().reg() != RAX) {
1236 __ movq(locs()->out().reg(), RAX); 1297 __ movq(locs()->out().reg(), RAX);
1237 } 1298 }
1238 } 1299 }
1239 1300
1240 } // namespace dart 1301 } // namespace dart
1241 1302
1242 #undef __ 1303 #undef __
1243 1304
1244 #endif // defined TARGET_ARCH_X64 1305 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698