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

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

Issue 14076005: Supports FrameLookup vm test on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/locations.h" 13 #include "vm/locations.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/parser.h" 15 #include "vm/parser.h"
16 #include "vm/simulator.h"
16 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
17 #include "vm/symbols.h" 18 #include "vm/symbols.h"
18 19
19 #define __ compiler->assembler()-> 20 #define __ compiler->assembler()->
20 21
21 namespace dart { 22 namespace dart {
22 23
23 DECLARE_FLAG(int, optimization_counter_threshold); 24 DECLARE_FLAG(int, optimization_counter_threshold);
24 DECLARE_FLAG(bool, propagate_ic_data); 25 DECLARE_FLAG(bool, propagate_ic_data);
25 26
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
188 summary->set_in(0, Location::RegisterLocation(A0)); // Value. 189 summary->set_in(0, Location::RegisterLocation(A0)); // Value.
189 summary->set_in(1, Location::RegisterLocation(A1)); // Instantiator. 190 summary->set_in(1, Location::RegisterLocation(A1)); // Instantiator.
190 summary->set_in(2, Location::RegisterLocation(A2)); // Type arguments. 191 summary->set_in(2, Location::RegisterLocation(A2)); // Type arguments.
191 summary->set_out(Location::RegisterLocation(A0)); 192 summary->set_out(Location::RegisterLocation(A0));
192 return summary; 193 return summary;
193 } 194 }
194 195
195 196
196 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 197 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const {
197 UNIMPLEMENTED(); 198 const intptr_t kNumInputs = 1;
198 return NULL; 199 const intptr_t kNumTemps = 0;
200 LocationSummary* locs =
201 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
202 locs->set_in(0, Location::RegisterLocation(A0));
203 locs->set_out(Location::RegisterLocation(A0));
204 return locs;
205 }
206
207
208 static void EmitAssertBoolean(Register reg,
209 intptr_t token_pos,
210 intptr_t deopt_id,
211 LocationSummary* locs,
212 FlowGraphCompiler* compiler) {
213 // Check that the type of the value is allowed in conditional context.
214 // Call the runtime if the object is not bool::true or bool::false.
215 ASSERT(locs->always_calls());
216 Label done;
217 __ BranchEqual(reg, Bool::True(), &done);
218 __ BranchEqual(reg, Bool::False(), &done);
219
220 __ Push(reg); // Push the source object.
221 compiler->GenerateCallRuntime(token_pos,
222 deopt_id,
223 kConditionTypeErrorRuntimeEntry,
224 locs);
225 // We should never return here.
226 __ break_(0);
227 __ Bind(&done);
199 } 228 }
200 229
201 230
202 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 231 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
203 UNIMPLEMENTED(); 232 Register obj = locs()->in(0).reg();
233 Register result = locs()->out().reg();
234
235 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
236 ASSERT(obj == result);
204 } 237 }
205 238
206 239
207 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { 240 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const {
208 UNIMPLEMENTED(); 241 UNIMPLEMENTED();
209 return NULL; 242 return NULL;
210 } 243 }
211 244
212 245
213 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 246 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
214 UNIMPLEMENTED(); 247 UNIMPLEMENTED();
215 } 248 }
216 249
217 250
218 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 251 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
219 UNIMPLEMENTED(); 252 const intptr_t kNumInputs = 2;
220 return NULL; 253 const bool is_checked_strict_equal =
254 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
255 if (receiver_class_id() == kMintCid) {
256 const intptr_t kNumTemps = 1;
257 LocationSummary* locs =
258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
259 locs->set_in(0, Location::RequiresFpuRegister());
260 locs->set_in(1, Location::RequiresFpuRegister());
261 locs->set_temp(0, Location::RequiresRegister());
262 locs->set_out(Location::RequiresRegister());
263 return locs;
264 }
265 if (receiver_class_id() == kDoubleCid) {
266 const intptr_t kNumTemps = 0;
267 LocationSummary* locs =
268 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
269 locs->set_in(0, Location::RequiresFpuRegister());
270 locs->set_in(1, Location::RequiresFpuRegister());
271 locs->set_out(Location::RequiresRegister());
272 return locs;
273 }
274 if (receiver_class_id() == kSmiCid) {
275 const intptr_t kNumTemps = 0;
276 LocationSummary* locs =
277 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
278 locs->set_in(0, Location::RegisterOrConstant(left()));
279 // Only one input can be a constant operand. The case of two constant
280 // operands should be handled by constant propagation.
281 locs->set_in(1, locs->in(0).IsConstant()
282 ? Location::RequiresRegister()
283 : Location::RegisterOrConstant(right()));
284 locs->set_out(Location::RequiresRegister());
285 return locs;
286 }
287 if (is_checked_strict_equal) {
288 const intptr_t kNumTemps = 1;
289 LocationSummary* locs =
290 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
291 locs->set_in(0, Location::RequiresRegister());
292 locs->set_in(1, Location::RequiresRegister());
293 locs->set_temp(0, Location::RequiresRegister());
294 locs->set_out(Location::RequiresRegister());
295 return locs;
296 }
297 if (IsPolymorphic()) {
298 const intptr_t kNumTemps = 1;
299 LocationSummary* locs =
300 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
301 UNIMPLEMENTED(); // TODO(regis): Verify register allocation.
302 return locs;
303 }
304 const intptr_t kNumTemps = 1;
305 LocationSummary* locs =
306 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
307 locs->set_in(0, Location::RegisterLocation(A1));
308 locs->set_in(1, Location::RegisterLocation(A0));
309 locs->set_temp(0, Location::RegisterLocation(T0));
310 locs->set_out(Location::RegisterLocation(V0));
311 return locs;
312 }
313
314
315 // A1: left.
316 // A0: right.
317 // Uses T0 to load ic_call_data.
318 // Result in V0.
319 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
320 intptr_t deopt_id,
321 intptr_t token_pos,
322 Token::Kind kind,
323 LocationSummary* locs,
324 const ICData& original_ic_data) {
325 if (!compiler->is_optimizing()) {
326 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
327 deopt_id,
328 token_pos);
329 }
330 const int kNumberOfArguments = 2;
331 const Array& kNoArgumentNames = Array::Handle();
332 const int kNumArgumentsChecked = 2;
333
334 Label check_identity;
335 __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
336 __ beq(A1, TMP1, &check_identity);
337 __ beq(A0, TMP1, &check_identity);
338
339 ICData& equality_ic_data = ICData::ZoneHandle();
340 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
341 ASSERT(!original_ic_data.IsNull());
342 if (original_ic_data.NumberOfChecks() == 0) {
343 // IC call for reoptimization populates original ICData.
344 equality_ic_data = original_ic_data.raw();
345 } else {
346 // Megamorphic call.
347 equality_ic_data = original_ic_data.AsUnaryClassChecks();
348 }
349 } else {
350 equality_ic_data = ICData::New(compiler->parsed_function().function(),
351 Symbols::EqualOperator(),
352 deopt_id,
353 kNumArgumentsChecked);
354 }
355 __ addiu(SP, SP, Immediate(-2 * kWordSize));
356 __ sw(A1, Address(SP, 1 * kWordSize));
357 __ sw(A0, Address(SP, 0 * kWordSize));
358 compiler->GenerateInstanceCall(deopt_id,
359 token_pos,
360 kNumberOfArguments,
361 kNoArgumentNames,
362 locs,
363 equality_ic_data);
364 Label check_ne;
365 __ b(&check_ne);
366
367 __ Bind(&check_identity);
368 Label equality_done;
369 if (compiler->is_optimizing()) {
370 // No need to update IC data.
371 Label is_true;
372 __ beq(A1, A0, &is_true);
373 __ LoadObject(V0, (kind == Token::kEQ) ? Bool::False() : Bool::True());
374 __ b(&equality_done);
375 __ Bind(&is_true);
376 __ LoadObject(V0, (kind == Token::kEQ) ? Bool::True() : Bool::False());
377 if (kind == Token::kNE) {
378 // Skip not-equal result conversion.
379 __ b(&equality_done);
380 }
381 } else {
382 // Call stub, load IC data in register. The stub will update ICData if
383 // necessary.
384 Register ic_data_reg = locs->temp(0).reg();
385 ASSERT(ic_data_reg == T0); // Stub depends on it.
386 __ LoadObject(ic_data_reg, equality_ic_data);
387 // Pass left in A1 and right in A0.
388 compiler->GenerateCall(token_pos,
389 &StubCode::EqualityWithNullArgLabel(),
390 PcDescriptors::kOther,
391 locs);
392 }
393 __ Bind(&check_ne);
394 if (kind == Token::kNE) {
395 Label true_label, done;
396 // Negate the condition: true label returns false and vice versa.
397 __ BranchEqual(V0, Bool::True(), &true_label);
398 __ LoadObject(V0, Bool::True());
399 __ b(&done);
400 __ Bind(&true_label);
401 __ LoadObject(V0, Bool::False());
402 __ Bind(&done);
403 }
404 __ Bind(&equality_done);
405 }
406
407
408 // Emit code when ICData's targets are all Object == (which is ===).
409 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler,
410 const ICData& ic_data,
411 const LocationSummary& locs,
412 Token::Kind kind,
413 BranchInstr* branch,
414 intptr_t deopt_id) {
415 UNIMPLEMENTED();
416 }
417
418
419 // First test if receiver is NULL, in which case === is applied.
420 // If type feedback was provided (lists of <class-id, target>), do a
421 // type by type check (either === or static call to the operator.
422 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
423 LocationSummary* locs,
424 Token::Kind kind,
425 BranchInstr* branch,
426 const ICData& ic_data,
427 intptr_t deopt_id,
428 intptr_t token_pos) {
429 UNIMPLEMENTED();
430 }
431
432
433 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
434 const LocationSummary& locs,
435 Token::Kind kind,
436 BranchInstr* branch) {
437 UNIMPLEMENTED();
438 }
439
440
441 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
442 const LocationSummary& locs,
443 Token::Kind kind,
444 BranchInstr* branch) {
445 UNIMPLEMENTED();
446 }
447
448
449 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
450 const LocationSummary& locs,
451 Token::Kind kind,
452 BranchInstr* branch) {
453 UNIMPLEMENTED();
221 } 454 }
222 455
223 456
224 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 457 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
225 UNIMPLEMENTED(); 458 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
459 BranchInstr* kNoBranch = NULL;
460 if (receiver_class_id() == kSmiCid) {
461 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
462 return;
463 }
464 if (receiver_class_id() == kMintCid) {
465 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
466 return;
467 }
468 if (receiver_class_id() == kDoubleCid) {
469 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
470 return;
471 }
472 const bool is_checked_strict_equal =
473 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
474 if (is_checked_strict_equal) {
475 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
476 deopt_id());
477 return;
478 }
479 if (IsPolymorphic()) {
480 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(),
481 deopt_id(), token_pos());
482 return;
483 }
484 Register left = locs()->in(0).reg();
485 Register right = locs()->in(1).reg();
486 ASSERT(left == A1);
487 ASSERT(right == A0);
488 EmitEqualityAsInstanceCall(compiler,
489 deopt_id(),
490 token_pos(),
491 kind(),
492 locs(),
493 *ic_data());
494 ASSERT(locs()->out().reg() == V0);
226 } 495 }
227 496
228 497
229 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 498 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
230 BranchInstr* branch) { 499 BranchInstr* branch) {
231 UNIMPLEMENTED(); 500 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
232 } 501 if (receiver_class_id() == kSmiCid) {
233 502 // Deoptimizes if both arguments not Smi.
234 503 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
504 return;
505 }
506 if (receiver_class_id() == kMintCid) {
507 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
508 return;
509 }
510 if (receiver_class_id() == kDoubleCid) {
511 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
512 return;
513 }
514 const bool is_checked_strict_equal =
515 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
516 if (is_checked_strict_equal) {
517 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
518 deopt_id());
519 return;
520 }
521 if (IsPolymorphic()) {
522 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(),
523 deopt_id(), token_pos());
524 return;
525 }
526 Register left = locs()->in(0).reg();
527 Register right = locs()->in(1).reg();
528 ASSERT(left == A1);
529 ASSERT(right == A0);
530 EmitEqualityAsInstanceCall(compiler,
531 deopt_id(),
532 token_pos(),
533 Token::kEQ, // kNE reverse occurs at branch.
534 locs(),
535 *ic_data());
536 if (branch->is_checked()) {
537 EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler);
538 }
539 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
540 __ CompareObject(CMPRES, V0, Bool::True());
541 branch->EmitBranchOnCondition(compiler, branch_condition);
542 }
543
544
235 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 545 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
236 UNIMPLEMENTED(); 546 UNIMPLEMENTED();
237 return NULL; 547 return NULL;
238 } 548 }
239 549
240 550
241 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 551 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
242 UNIMPLEMENTED(); 552 UNIMPLEMENTED();
243 } 553 }
244 554
(...skipping 20 matching lines...) Expand all
265 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 575 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
266 ASSERT(locs()->temp(0).reg() == A1); 576 ASSERT(locs()->temp(0).reg() == A1);
267 ASSERT(locs()->temp(1).reg() == A2); 577 ASSERT(locs()->temp(1).reg() == A2);
268 ASSERT(locs()->temp(2).reg() == T5); 578 ASSERT(locs()->temp(2).reg() == T5);
269 Register result = locs()->out().reg(); 579 Register result = locs()->out().reg();
270 580
271 // Push the result place holder initialized to NULL. 581 // Push the result place holder initialized to NULL.
272 __ PushObject(Object::ZoneHandle()); 582 __ PushObject(Object::ZoneHandle());
273 // Pass a pointer to the first argument in A2. 583 // Pass a pointer to the first argument in A2.
274 if (!function().HasOptionalParameters()) { 584 if (!function().HasOptionalParameters()) {
275 __ addiu(A2, FP, Immediate((kLastParamSlotIndex + 585 __ AddImmediate(A2, FP, (kLastParamSlotIndex +
276 function().NumParameters() - 1) * kWordSize)); 586 function().NumParameters() - 1) * kWordSize);
277 } else { 587 } else {
278 __ addiu(A2, FP, Immediate(kFirstLocalSlotIndex * kWordSize)); 588 __ AddImmediate(A2, FP, kFirstLocalSlotIndex * kWordSize);
279 } 589 }
280 // Compute the effective address. When running under the simulator, 590 // Compute the effective address. When running under the simulator,
281 // this is a redirection address that forces the simulator to call 591 // this is a redirection address that forces the simulator to call
282 // into the runtime system. 592 // into the runtime system.
283 uword entry = reinterpret_cast<uword>(native_c_function()); 593 uword entry = reinterpret_cast<uword>(native_c_function());
284 #if defined(USING_SIMULATOR) 594 #if defined(USING_SIMULATOR)
285 entry = Simulator::RedirectExternalReference(entry, Simulator::kNativeCall); 595 entry = Simulator::RedirectExternalReference(entry, Simulator::kNativeCall);
286 #endif 596 #endif
287 __ LoadImmediate(T5, entry); 597 __ LoadImmediate(T5, entry);
288 __ LoadImmediate(A1, NativeArguments::ComputeArgcTag(function())); 598 __ LoadImmediate(A1, NativeArguments::ComputeArgcTag(function()));
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 } 1022 }
713 1023
714 1024
715 LocationSummary* BranchInstr::MakeLocationSummary() const { 1025 LocationSummary* BranchInstr::MakeLocationSummary() const {
716 UNREACHABLE(); 1026 UNREACHABLE();
717 return NULL; 1027 return NULL;
718 } 1028 }
719 1029
720 1030
721 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1031 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
722 UNIMPLEMENTED(); 1032 comparison()->EmitBranchCode(compiler, this);
723 } 1033 }
724 1034
725 1035
726 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 1036 LocationSummary* CheckClassInstr::MakeLocationSummary() const {
727 UNIMPLEMENTED(); 1037 UNIMPLEMENTED();
728 return NULL; 1038 return NULL;
729 } 1039 }
730 1040
731 1041
732 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1042 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 return NULL; 1138 return NULL;
829 } 1139 }
830 1140
831 1141
832 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1142 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
833 UNIMPLEMENTED(); 1143 UNIMPLEMENTED();
834 } 1144 }
835 1145
836 1146
837 LocationSummary* GotoInstr::MakeLocationSummary() const { 1147 LocationSummary* GotoInstr::MakeLocationSummary() const {
838 UNIMPLEMENTED(); 1148 return new LocationSummary(0, 0, LocationSummary::kNoCall);
839 return NULL;
840 } 1149 }
841 1150
842 1151
843 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1152 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
844 UNIMPLEMENTED(); 1153 // Add deoptimization descriptor for deoptimizing instructions
1154 // that may be inserted before this instruction.
1155 if (!compiler->is_optimizing()) {
1156 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
1157 GetDeoptId(),
1158 0); // No token position.
1159 }
1160
1161 if (HasParallelMove()) {
1162 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1163 }
1164
1165 // We can fall through if the successor is the next block in the list.
1166 // Otherwise, we need a jump.
1167 if (!compiler->CanFallThroughTo(successor())) {
1168 __ b(compiler->GetJumpLabel(successor()));
1169 }
1170 }
1171
1172
1173 static Condition NegateCondition(Condition condition) {
1174 switch (condition) {
1175 case EQ: return NE;
1176 case NE: return EQ;
1177 default:
1178 OS::Print("Error: Condition not recognized: %d\n", condition);
1179 UNIMPLEMENTED();
1180 return EQ;
1181 }
845 } 1182 }
846 1183
847 1184
848 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler, 1185 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
849 bool value) { 1186 bool value) {
850 UNIMPLEMENTED(); 1187 if (value && !compiler->CanFallThroughTo(true_successor())) {
1188 __ b(compiler->GetJumpLabel(true_successor()));
1189 } else if (!value && !compiler->CanFallThroughTo(false_successor())) {
1190 __ b(compiler->GetJumpLabel(false_successor()));
1191 }
851 } 1192 }
852 1193
853 1194
1195 // The comparison result is in CRESREG.
regis 2013/04/10 20:53:00 What is CRESREG? CMPRES?
zra 2013/04/10 21:59:05 Done.
854 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler, 1196 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler,
855 Condition true_condition) { 1197 Condition true_condition) {
856 UNIMPLEMENTED(); 1198 if (compiler->CanFallThroughTo(false_successor())) {
1199 // If the next block is the false successor we will fall through to it.
1200 __ BranchOnCondition(CMPRES, compiler->GetJumpLabel(true_successor()),
1201 true_condition);
1202 } else {
1203 // If the next block is the true successor we negate comparison and fall
1204 // through to it.
1205 Condition false_condition = NegateCondition(true_condition);
1206 __ BranchOnCondition(CMPRES, compiler->GetJumpLabel(false_successor()),
1207 false_condition);
1208
1209 // Fall through or jump to the true successor.
1210 if (!compiler->CanFallThroughTo(true_successor())) {
1211 __ b(compiler->GetJumpLabel(true_successor()));
1212 }
1213 }
857 } 1214 }
858 1215
859 1216
860 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 1217 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
861 UNIMPLEMENTED(); 1218 UNIMPLEMENTED();
862 return NULL; 1219 return NULL;
863 } 1220 }
864 1221
865 1222
866 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1223 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
867 UNIMPLEMENTED(); 1224 UNIMPLEMENTED();
868 } 1225 }
869 1226
870 1227
871 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { 1228 LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
872 UNIMPLEMENTED(); 1229 const intptr_t kNumInputs = 2;
873 return NULL; 1230 const intptr_t kNumTemps = 0;
1231 LocationSummary* locs =
1232 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1233 locs->set_in(0, Location::RegisterOrConstant(left()));
1234 locs->set_in(1, Location::RegisterOrConstant(right()));
1235 locs->set_out(Location::RequiresRegister());
1236 return locs;
874 } 1237 }
875 1238
876 1239
1240 // Special code for numbers (compare values instead of references.)
877 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1241 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
878 UNIMPLEMENTED(); 1242 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1243 Location left = locs()->in(0);
1244 Location right = locs()->in(1);
1245 if (left.IsConstant() && right.IsConstant()) {
1246 // TODO(vegorov): should be eliminated earlier by constant propagation.
1247 const bool result = (kind() == Token::kEQ_STRICT) ?
1248 left.constant().raw() == right.constant().raw() :
1249 left.constant().raw() != right.constant().raw();
1250 __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
1251 return;
1252 }
1253 if (left.IsConstant()) {
1254 compiler->EmitEqualityRegConstCompare(right.reg(),
1255 left.constant(),
1256 needs_number_check());
1257 } else if (right.IsConstant()) {
1258 compiler->EmitEqualityRegConstCompare(left.reg(),
1259 right.constant(),
1260 needs_number_check());
1261 } else {
1262 compiler->EmitEqualityRegRegCompare(left.reg(),
1263 right.reg(),
1264 needs_number_check());
1265 }
1266
1267 Register result = locs()->out().reg();
1268 Label load_true, done;
1269 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
1270 __ BranchOnCondition(CMPRES, &load_true, true_condition);
regis 2013/04/10 20:53:00 It would be clearer to write: if (kind() == Token:
zra 2013/04/10 21:59:05 Done.
1271 __ LoadObject(result, Bool::False());
1272 __ b(&done);
1273 __ Bind(&load_true);
1274 __ LoadObject(result, Bool::True());
1275 __ Bind(&done);
879 } 1276 }
880 1277
881 1278
882 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1279 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
883 BranchInstr* branch) { 1280 BranchInstr* branch) {
884 UNIMPLEMENTED(); 1281 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1282 Location left = locs()->in(0);
1283 Location right = locs()->in(1);
1284 if (left.IsConstant() && right.IsConstant()) {
1285 // TODO(vegorov): should be eliminated earlier by constant propagation.
1286 const bool result = (kind() == Token::kEQ_STRICT) ?
1287 left.constant().raw() == right.constant().raw() :
1288 left.constant().raw() != right.constant().raw();
1289 branch->EmitBranchOnValue(compiler, result);
1290 return;
1291 }
1292 if (left.IsConstant()) {
1293 compiler->EmitEqualityRegConstCompare(right.reg(),
1294 left.constant(),
1295 needs_number_check());
1296 } else if (right.IsConstant()) {
1297 compiler->EmitEqualityRegConstCompare(left.reg(),
1298 right.constant(),
1299 needs_number_check());
1300 } else {
1301 compiler->EmitEqualityRegRegCompare(left.reg(),
1302 right.reg(),
1303 needs_number_check());
1304 }
1305
1306 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
1307 branch->EmitBranchOnCondition(compiler, true_condition);
885 } 1308 }
886 1309
887 1310
888 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1311 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
889 UNIMPLEMENTED(); 1312 UNIMPLEMENTED();
890 } 1313 }
891 1314
892 1315
893 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 1316 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
894 UNIMPLEMENTED(); 1317 UNIMPLEMENTED();
(...skipping 22 matching lines...) Expand all
917 return NULL; 1340 return NULL;
918 } 1341 }
919 1342
920 1343
921 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1344 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
922 UNIMPLEMENTED(); 1345 UNIMPLEMENTED();
923 } 1346 }
924 1347
925 1348
926 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 1349 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
927 UNIMPLEMENTED(); 1350 return MakeCallSummary();
928 return NULL;
929 } 1351 }
930 1352
931 1353
932 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1354 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
933 UNIMPLEMENTED(); 1355 const Class& cls = Class::ZoneHandle(constructor().Owner());
1356 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
1357 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1358 compiler->GenerateCall(token_pos(),
1359 &label,
1360 PcDescriptors::kOther,
1361 locs());
1362 __ Drop(ArgumentCount()); // Discard arguments.
934 } 1363 }
935 1364
936 1365
937 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { 1366 LocationSummary* CreateClosureInstr::MakeLocationSummary() const {
938 UNIMPLEMENTED(); 1367 UNIMPLEMENTED();
939 return NULL; 1368 return NULL;
940 } 1369 }
941 1370
942 1371
943 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1372 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
944 UNIMPLEMENTED(); 1373 UNIMPLEMENTED();
945 } 1374 }
946 1375
947 } // namespace dart 1376 } // namespace dart
948 1377
949 #endif // defined TARGET_ARCH_MIPS 1378 #endif // defined TARGET_ARCH_MIPS
950 1379
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698