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

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

Issue 10543013: More code for ia32, more shared code. (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
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 "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/parser.h" 14 #include "vm/parser.h"
15 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
16 16
17 #define __ compiler->assembler()-> 17 #define __ compiler->assembler()->
18 18
19 namespace dart { 19 namespace dart {
20 20
21 DECLARE_FLAG(int, optimization_counter_threshold); 21 DECLARE_FLAG(int, optimization_counter_threshold);
22 DECLARE_FLAG(bool, trace_functions); 22 DECLARE_FLAG(bool, trace_functions);
23 23
24 24
25 // True iff. the arguments to a call will be properly pushed and can
26 // be popped after the call.
27 template <typename T> static bool VerifyCallComputation(T* comp) {
28 // Argument values should be consecutive temps.
29 //
30 // TODO(kmillikin): implement stack height tracking so we can also assert
31 // they are on top of the stack.
32 intptr_t previous = -1;
33 for (int i = 0; i < comp->ArgumentCount(); ++i) {
34 Value* val = comp->ArgumentAt(i);
35 if (!val->IsUse()) return false;
36 intptr_t current = val->AsUse()->definition()->temp_index();
37 if (i != 0) {
38 if (current != (previous + 1)) return false;
39 }
40 previous = current;
41 }
42 return true;
43 }
44
45
46 // Truee iff. the v2 is above v1 on stack, or one of them is constant.
47 static bool VerifyValues(Value* v1, Value* v2) {
48 ASSERT(v1->IsUse() && v2->IsUse());
49 return (v1->AsUse()->definition()->temp_index() + 1) ==
50 v2->AsUse()->definition()->temp_index();
51 }
52
53
54 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 25 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
55 computation()->EmitNativeCode(compiler); 26 computation()->EmitNativeCode(compiler);
56 __ pushq(locs()->out().reg()); 27 __ pushq(locs()->out().reg());
57 } 28 }
58 29
59 30
60 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
61 // Nothing to do.
62 }
63
64
65 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
66 __ Bind(compiler->GetBlockLabel(this));
67 }
68
69
70 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
71 __ Bind(compiler->GetBlockLabel(this));
72 if (HasTryIndex()) {
73 compiler->AddExceptionHandler(try_index(),
74 compiler->assembler()->CodeSize());
75 }
76 }
77
78
79 LocationSummary* ThrowInstr::MakeLocationSummary() const {
80 const int kNumInputs = 0;
81 const int kNumTemps = 0;
82 return new LocationSummary(kNumInputs, kNumTemps);
83 }
84
85
86 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
87 ASSERT(exception()->IsUse());
88 compiler->GenerateCallRuntime(cid(),
89 token_index(),
90 try_index(),
91 kThrowRuntimeEntry);
92 __ int3();
93 }
94
95
96 LocationSummary* ReThrowInstr::MakeLocationSummary() const {
97 const int kNumInputs = 0;
98 const int kNumTemps = 0;
99 return new LocationSummary(kNumInputs, kNumTemps);
100 }
101
102
103 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
104 ASSERT(exception()->IsUse());
105 ASSERT(stack_trace()->IsUse());
106 compiler->GenerateCallRuntime(cid(),
107 token_index(),
108 try_index(),
109 kReThrowRuntimeEntry);
110 __ int3();
111 }
112
113
114 LocationSummary* BranchInstr::MakeLocationSummary() const {
115 const int kNumInputs = 1;
116 const int kNumTemps = 0;
117 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
118 locs->set_in(0, Location::RequiresRegister());
119 return locs;
120 }
121
122
123 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
124 Register value = locs()->in(0).reg();
125
126 __ CompareObject(value, Bool::ZoneHandle(Bool::True()));
127 if (compiler->IsNextBlock(false_successor())) {
128 // If the next block is the false successor we will fall through to it if
129 // comparison with true fails.
130 __ j(EQUAL, compiler->GetBlockLabel(true_successor()));
131 } else {
132 ASSERT(compiler->IsNextBlock(true_successor()));
133 // If the next block is the true successor we negate comparison and fall
134 // through to it.
135 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor()));
136 }
137 }
138
139
140 LocationSummary* ReturnInstr::MakeLocationSummary() const { 31 LocationSummary* ReturnInstr::MakeLocationSummary() const {
141 const intptr_t kNumInputs = 1; 32 const intptr_t kNumInputs = 1;
142 const intptr_t kNumTemps = 1; 33 const intptr_t kNumTemps = 1;
143 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 34 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
144 locs->set_in(0, Location::RegisterLocation(RAX)); 35 locs->set_in(0, Location::RegisterLocation(RAX));
145 locs->set_temp(0, Location::RequiresRegister()); 36 locs->set_temp(0, Location::RequiresRegister());
146 return locs; 37 return locs;
147 } 38 }
148 39
149 40
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 __ nop(1); 90 __ nop(1);
200 __ nop(1); 91 __ nop(1);
201 __ nop(1); 92 __ nop(1);
202 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 93 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
203 cid(), 94 cid(),
204 token_index(), 95 token_index(),
205 CatchClauseNode::kInvalidTryIndex); 96 CatchClauseNode::kInvalidTryIndex);
206 } 97 }
207 98
208 99
209 LocationSummary* CurrentContextComp::MakeLocationSummary() const {
210 return LocationSummary::Make(0, Location::RequiresRegister());
211 }
212
213
214 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
215 __ movq(locs()->out().reg(), CTX);
216 }
217
218
219 LocationSummary* StoreContextComp::MakeLocationSummary() const {
220 LocationSummary* summary = new LocationSummary(1, 0);
221 summary->set_in(0, Location::RegisterLocation(CTX));
222 return summary;
223 }
224
225
226 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
227 // Nothing to do. Context register were loaded by register allocator.
228 ASSERT(locs()->in(0).reg() == CTX);
229 }
230
231
232 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
233 return LocationSummary::Make(2, Location::SameAsFirstInput());
234 }
235
236
237 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
238 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
239 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
240
241 Register left = locs()->in(0).reg();
242 Register right = locs()->in(1).reg();
243 Register result = locs()->out().reg();
244
245 __ cmpq(left, right);
246 Label load_true, done;
247 if (kind() == Token::kEQ_STRICT) {
248 __ j(EQUAL, &load_true, Assembler::kNearJump);
249 } else {
250 ASSERT(kind() == Token::kNE_STRICT);
251 __ j(NOT_EQUAL, &load_true, Assembler::kNearJump);
252 }
253 __ LoadObject(result, bool_false);
254 __ jmp(&done, Assembler::kNearJump);
255 __ Bind(&load_true);
256 __ LoadObject(result, bool_true);
257 __ Bind(&done);
258 }
259
260
261 // Generic summary for call instructions that have all arguments pushed 100 // Generic summary for call instructions that have all arguments pushed
262 // on the stack and return the result in a fixed register RAX. 101 // on the stack and return the result in a fixed register RAX.
263 static LocationSummary* MakeCallSummary() { 102 LocationSummary* Computation::MakeCallSummary() {
264 LocationSummary* result = new LocationSummary(0, 0); 103 LocationSummary* result = new LocationSummary(0, 0);
265 result->set_out(Location::RegisterLocation(RAX)); 104 result->set_out(Location::RegisterLocation(RAX));
266 return result; 105 return result;
267 } 106 }
268 107
269 108
270 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 109 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
271 return MakeCallSummary(); 110 const intptr_t kNumInputs = 0;
272 } 111 const intptr_t kNumTemps = 1;
273 112 LocationSummary* result = new LocationSummary(kNumInputs, kNumTemps);
274 113 result->set_out(Location::RegisterLocation(RAX));
275 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 114 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
276 ASSERT(VerifyCallComputation(this)); 115 return result;
277 // The arguments to the stub include the closure. The arguments
278 // descriptor describes the closure's arguments (and so does not include
279 // the closure).
280 int argument_count = ArgumentCount();
281 const Array& arguments_descriptor =
282 CodeGenerator::ArgumentsDescriptor(argument_count - 1,
283 argument_names());
284 __ LoadObject(R10, arguments_descriptor);
285
286 compiler->GenerateCall(token_index(),
287 try_index(),
288 &StubCode::CallClosureFunctionLabel(),
289 PcDescriptors::kOther);
290 __ Drop(argument_count);
291 }
292
293
294 LocationSummary* InstanceCallComp::MakeLocationSummary() const {
295 return MakeCallSummary();
296 }
297
298
299 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
300 ASSERT(VerifyCallComputation(this));
301 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
302 cid(),
303 token_index(),
304 try_index());
305 compiler->GenerateInstanceCall(cid(),
306 token_index(),
307 try_index(),
308 function_name(),
309 ArgumentCount(),
310 argument_names(),
311 checked_argument_count());
312 }
313
314
315 LocationSummary* StaticCallComp::MakeLocationSummary() const {
316 return MakeCallSummary();
317 }
318
319
320 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
321 ASSERT(VerifyCallComputation(this));
322 compiler->GenerateStaticCall(cid(),
323 token_index(),
324 try_index(),
325 function(),
326 ArgumentCount(),
327 argument_names());
328 } 116 }
329 117
330 118
331 LocationSummary* LoadLocalComp::MakeLocationSummary() const { 119 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
332 return LocationSummary::Make(0, Location::RequiresRegister()); 120 return LocationSummary::Make(0, Location::RequiresRegister());
333 } 121 }
334 122
335 123
336 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 124 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
337 Register result = locs()->out().reg(); 125 Register result = locs()->out().reg();
(...skipping 23 matching lines...) Expand all
361 Register result = locs()->out().reg(); 149 Register result = locs()->out().reg();
362 if (value().IsSmi()) { 150 if (value().IsSmi()) {
363 int64_t imm = reinterpret_cast<int64_t>(value().raw()); 151 int64_t imm = reinterpret_cast<int64_t>(value().raw());
364 __ movq(result, Immediate(imm)); 152 __ movq(result, Immediate(imm));
365 } else { 153 } else {
366 __ LoadObject(result, value()); 154 __ LoadObject(result, value());
367 } 155 }
368 } 156 }
369 157
370 158
371 LocationSummary* UseVal::MakeLocationSummary() const {
372 return NULL;
373 }
374
375
376 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) {
377 UNIMPLEMENTED();
378 }
379
380
381 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { 159 LocationSummary* AssertAssignableComp::MakeLocationSummary() const {
382 LocationSummary* summary = new LocationSummary(3, 0); 160 LocationSummary* summary = new LocationSummary(3, 0);
383 summary->set_in(0, Location::RegisterLocation(RAX)); 161 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
384 summary->set_in(1, Location::RegisterLocation(RCX)); 162 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator.
385 summary->set_in(2, Location::RegisterLocation(RDX)); 163 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments.
386 summary->set_out(Location::RegisterLocation(RAX)); 164 summary->set_out(Location::RegisterLocation(RAX));
387 return summary; 165 return summary;
388 } 166 }
389 167
390 168
391 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
392 ASSERT(locs()->in(0).reg() == RAX); // Value.
393 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
394 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
395
396 compiler->GenerateAssertAssignable(cid(),
397 token_index(),
398 try_index(),
399 dst_type(),
400 dst_name());
401 ASSERT(locs()->in(0).reg() == locs()->out().reg());
402 }
403
404
405 LocationSummary* AssertBooleanComp::MakeLocationSummary() const {
406 return LocationSummary::Make(1, Location::SameAsFirstInput());
407 }
408
409
410 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { 169 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) {
411 Register obj = locs()->in(0).reg(); 170 Register obj = locs()->in(0).reg();
412 Register result = locs()->out().reg(); 171 Register result = locs()->out().reg();
413 172
414 // Check that the type of the value is allowed in conditional context. 173 // Check that the type of the value is allowed in conditional context.
415 // Call the runtime if the object is not bool::true or bool::false. 174 // Call the runtime if the object is not bool::true or bool::false.
416 Label done; 175 Label done;
417 __ CompareObject(obj, Bool::ZoneHandle(Bool::True())); 176 __ CompareObject(obj, Bool::ZoneHandle(Bool::True()));
418 __ j(EQUAL, &done, Assembler::kNearJump); 177 __ j(EQUAL, &done, Assembler::kNearJump);
419 __ CompareObject(obj, Bool::ZoneHandle(Bool::False())); 178 __ CompareObject(obj, Bool::ZoneHandle(Bool::False()));
420 __ j(EQUAL, &done, Assembler::kNearJump); 179 __ j(EQUAL, &done, Assembler::kNearJump);
421 180
422 __ pushq(Immediate(Smi::RawValue(token_index()))); // Source location. 181 __ pushq(Immediate(Smi::RawValue(token_index()))); // Source location.
423 __ pushq(obj); // Push the source object. 182 __ pushq(obj); // Push the source object.
424 compiler->GenerateCallRuntime(cid(), 183 compiler->GenerateCallRuntime(cid(),
425 token_index(), 184 token_index(),
426 try_index(), 185 try_index(),
427 kConditionTypeErrorRuntimeEntry); 186 kConditionTypeErrorRuntimeEntry);
428 // We should never return here. 187 // We should never return here.
429 __ int3(); 188 __ int3();
430 189
431 __ Bind(&done); 190 __ Bind(&done);
432 ASSERT(obj == result); 191 ASSERT(obj == result);
433 } 192 }
434 193
435 194
436 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 195 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
437 LocationSummary* locs = new LocationSummary(2, 0); 196 LocationSummary* locs = new LocationSummary(2, 0);
438 locs->set_in(0, Location::RegisterLocation(RAX)); 197 locs->set_in(0, Location::RequiresRegister());
439 locs->set_in(1, Location::RequiresRegister()); 198 locs->set_in(1, Location::RequiresRegister());
440 locs->set_out(Location::RegisterLocation(RAX)); 199 locs->set_out(Location::RegisterLocation(RAX));
441 return locs; 200 return locs;
442 } 201 }
443 202
444 203
445 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 204 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
446 Register left = locs()->in(0).reg(); 205 Register left = locs()->in(0).reg();
447 Register right = locs()->in(1).reg(); 206 Register right = locs()->in(1).reg();
448 Register result = locs()->out().reg(); 207 Register result = locs()->out().reg();
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 379
621 380
622 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 381 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
623 Register instance = locs()->in(0).reg(); 382 Register instance = locs()->in(0).reg();
624 Register result = locs()->out().reg(); 383 Register result = locs()->out().reg();
625 384
626 __ movq(result, FieldAddress(instance, field().Offset())); 385 __ movq(result, FieldAddress(instance, field().Offset()));
627 } 386 }
628 387
629 388
630 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const {
631 return LocationSummary::Make(2, Location::RequiresRegister());
632 }
633
634
635 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
636 ASSERT(VerifyValues(instance(), value()));
637 Register instance = locs()->in(0).reg();
638 Register value = locs()->in(1).reg();
639 Register result = locs()->out().reg();
640
641 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()),
642 value);
643 // TODO(fschneider): Consider eliminating this move by specifying a
644 // SameAsSecondInput for the result.
645 if (result != value) {
646 __ movq(result, value);
647 }
648 }
649
650
651 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { 389 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
652 return LocationSummary::Make(0, Location::RequiresRegister()); 390 return LocationSummary::Make(0, Location::RequiresRegister());
653 } 391 }
654 392
655 393
656 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 394 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
657 Register result = locs()->out().reg(); 395 Register result = locs()->out().reg();
658 __ LoadObject(result, field()); 396 __ LoadObject(result, field());
659 __ movq(result, FieldAddress(result, Field::value_offset())); 397 __ movq(result, FieldAddress(result, Field::value_offset()));
660 } 398 }
661 399
662 400
663 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const {
664 LocationSummary* locs = new LocationSummary(1, 1);
665 locs->set_in(0, Location::RequiresRegister());
666 locs->set_temp(0, Location::RequiresRegister());
667 locs->set_out(Location::SameAsFirstInput());
668 return locs;
669 }
670
671
672 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
673 Register value = locs()->in(0).reg();
674 Register temp = locs()->temp(0).reg();
675 ASSERT(locs()->out().reg() == value);
676
677 __ LoadObject(temp, field());
678 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
679 }
680
681
682 LocationSummary* BooleanNegateComp::MakeLocationSummary() const {
683 return LocationSummary::Make(1, Location::RequiresRegister());
684 }
685
686
687 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
688 Register value = locs()->in(0).reg();
689 Register result = locs()->out().reg();
690
691 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
692 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
693 Label done;
694 __ LoadObject(result, bool_true);
695 __ cmpq(result, value);
696 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
697 __ LoadObject(result, bool_false);
698 __ Bind(&done);
699 }
700
701
702 LocationSummary* InstanceOfComp::MakeLocationSummary() const { 401 LocationSummary* InstanceOfComp::MakeLocationSummary() const {
703 LocationSummary* summary = new LocationSummary(3, 0); 402 LocationSummary* summary = new LocationSummary(3, 0);
704 summary->set_in(0, Location::RegisterLocation(RAX)); 403 summary->set_in(0, Location::RegisterLocation(RAX));
705 summary->set_in(1, Location::RegisterLocation(RCX)); 404 summary->set_in(1, Location::RegisterLocation(RCX));
706 summary->set_in(2, Location::RegisterLocation(RDX)); 405 summary->set_in(2, Location::RegisterLocation(RDX));
707 summary->set_out(Location::RegisterLocation(RAX)); 406 summary->set_out(Location::RegisterLocation(RAX));
708 return summary; 407 return summary;
709 } 408 }
710 409
711 410
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 Register result_reg = locs()->out().reg(); 442 Register result_reg = locs()->out().reg();
744 443
745 // 1. Allocate the array. R10 = length, RBX = element type. 444 // 1. Allocate the array. R10 = length, RBX = element type.
746 ASSERT(temp_reg == R10); 445 ASSERT(temp_reg == R10);
747 ASSERT(locs()->in(0).reg() == RBX); 446 ASSERT(locs()->in(0).reg() == RBX);
748 __ movq(temp_reg, Immediate(Smi::RawValue(ElementCount()))); 447 __ movq(temp_reg, Immediate(Smi::RawValue(ElementCount())));
749 compiler->GenerateCall(token_index(), 448 compiler->GenerateCall(token_index(),
750 try_index(), 449 try_index(),
751 &StubCode::AllocateArrayLabel(), 450 &StubCode::AllocateArrayLabel(),
752 PcDescriptors::kOther); 451 PcDescriptors::kOther);
753 452 ASSERT(result_reg == RAX);
754 // 2. Initialize the array in result_reg with the element values. 453 // 2. Initialize the array in result_reg with the element values.
755 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); 454 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset()));
756 for (int i = ElementCount() - 1; i >= 0; --i) { 455 for (int i = ElementCount() - 1; i >= 0; --i) {
757 ASSERT(ElementAt(i)->IsUse()); 456 ASSERT(ElementAt(i)->IsUse());
758 __ popq(Address(temp_reg, i * kWordSize)); 457 __ popq(Address(temp_reg, i * kWordSize));
759 } 458 }
760 } 459 }
761 460
762 461
763 LocationSummary* CreateClosureComp::MakeLocationSummary() const {
764 return MakeCallSummary();
765 }
766
767
768 void CreateClosureComp::EmitNativeCode(FlowGraphCompiler* compiler) {
769 const Function& closure_function = function();
770 const Code& stub = Code::Handle(
771 StubCode::GetAllocationStubForClosure(closure_function));
772 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
773 compiler->GenerateCall(token_index(), try_index(), &label,
774 PcDescriptors::kOther);
775 __ Drop(2); // Discard type arguments and receiver.
776 }
777
778
779 LocationSummary* AllocateObjectComp::MakeLocationSummary() const {
780 return MakeCallSummary();
781 }
782
783
784 void AllocateObjectComp::EmitNativeCode(FlowGraphCompiler* compiler) {
785 const Class& cls = Class::ZoneHandle(constructor().owner());
786 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
787 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
788 compiler->GenerateCall(token_index(),
789 try_index(),
790 &label,
791 PcDescriptors::kOther);
792 __ Drop(arguments().length()); // Discard arguments.
793 }
794
795
796 LocationSummary* AllocateObjectWithBoundsCheckComp:: 462 LocationSummary* AllocateObjectWithBoundsCheckComp::
797 MakeLocationSummary() const { 463 MakeLocationSummary() const {
798 return LocationSummary::Make(2, Location::RequiresRegister()); 464 return LocationSummary::Make(2, Location::RequiresRegister());
799 } 465 }
800 466
801 467
802 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 468 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
803 FlowGraphCompiler* compiler) { 469 FlowGraphCompiler* compiler) {
804 const Class& cls = Class::ZoneHandle(constructor().owner()); 470 const Class& cls = Class::ZoneHandle(constructor().owner());
805 Register type_arguments = locs()->in(0).reg(); 471 Register type_arguments = locs()->in(0).reg();
(...skipping 23 matching lines...) Expand all
829 495
830 496
831 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 497 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
832 Register obj = locs()->in(0).reg(); 498 Register obj = locs()->in(0).reg();
833 Register result = locs()->out().reg(); 499 Register result = locs()->out().reg();
834 500
835 __ movq(result, FieldAddress(obj, offset_in_bytes())); 501 __ movq(result, FieldAddress(obj, offset_in_bytes()));
836 } 502 }
837 503
838 504
839 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const {
840 return LocationSummary::Make(2, Location::SameAsFirstInput());
841 }
842
843
844 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
845 Register value_reg = locs()->in(0).reg();
846 Register dest_reg = locs()->in(1).reg();
847 ASSERT(value_reg == locs()->out().reg());
848
849 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
850 value_reg);
851 }
852
853
854 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 505 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
855 const intptr_t kNumInputs = 1; 506 const intptr_t kNumInputs = 1;
856 const intptr_t kNumTemps = 0; 507 const intptr_t kNumTemps = 0;
857 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 508 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
858 locs->set_in(0, Location::RequiresRegister()); 509 locs->set_in(0, Location::RequiresRegister());
859 locs->set_out(Location::SameAsFirstInput()); 510 locs->set_out(Location::SameAsFirstInput());
860 return locs; 511 return locs;
861 } 512 }
862 513
863 514
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 __ movq(R10, Immediate(num_context_variables())); 696 __ movq(R10, Immediate(num_context_variables()));
1046 const ExternalLabel label("alloc_context", 697 const ExternalLabel label("alloc_context",
1047 StubCode::AllocateContextEntryPoint()); 698 StubCode::AllocateContextEntryPoint());
1048 compiler->GenerateCall(token_index(), 699 compiler->GenerateCall(token_index(),
1049 try_index(), 700 try_index(),
1050 &label, 701 &label,
1051 PcDescriptors::kOther); 702 PcDescriptors::kOther);
1052 } 703 }
1053 704
1054 705
1055 LocationSummary* ChainContextComp::MakeLocationSummary() const {
1056 return LocationSummary::Make(1, Location::NoLocation());
1057 }
1058
1059
1060 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1061 Register context_value = locs()->in(0).reg();
1062
1063 // Chain the new context in context_value to its parent in CTX.
1064 __ StoreIntoObject(context_value,
1065 FieldAddress(context_value, Context::parent_offset()),
1066 CTX);
1067 // Set new context as current context.
1068 __ movq(CTX, context_value);
1069 }
1070
1071
1072 LocationSummary* CloneContextComp::MakeLocationSummary() const { 706 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1073 return LocationSummary::Make(1, Location::RequiresRegister()); 707 return LocationSummary::Make(1, Location::RequiresRegister());
1074 } 708 }
1075 709
1076 710
1077 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 711 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1078 Register context_value = locs()->in(0).reg(); 712 Register context_value = locs()->in(0).reg();
1079 Register result = locs()->out().reg(); 713 Register result = locs()->out().reg();
1080 714
1081 __ PushObject(Object::ZoneHandle()); // Make room for the result. 715 __ PushObject(Object::ZoneHandle()); // Make room for the result.
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 } else { 1063 } else {
1430 UNREACHABLE(); 1064 UNREACHABLE();
1431 } 1065 }
1432 } 1066 }
1433 1067
1434 } // namespace dart 1068 } // namespace dart
1435 1069
1436 #undef __ 1070 #undef __
1437 1071
1438 #endif // defined TARGET_ARCH_X64 1072 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/intermediate_language.cc ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698