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

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
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/resolver_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_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 CMPRES.
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 if (true_condition == EQ) {
1201 __ beq(CMPRES, ZR, compiler->GetJumpLabel(true_successor()));
1202 } else {
1203 ASSERT(true_condition == NE);
1204 __ bne(CMPRES, ZR, compiler->GetJumpLabel(true_successor()));
1205 }
1206 } else {
1207 // If the next block is the true successor we negate comparison and fall
1208 // through to it.
1209 Condition false_condition = NegateCondition(true_condition);
1210 if (false_condition == EQ) {
1211 __ beq(CMPRES, ZR, compiler->GetJumpLabel(false_successor()));
1212 } else {
1213 ASSERT(false_condition == NE);
1214 __ bne(CMPRES, ZR, compiler->GetJumpLabel(false_successor()));
1215 }
1216 // Fall through or jump to the true successor.
1217 if (!compiler->CanFallThroughTo(true_successor())) {
1218 __ b(compiler->GetJumpLabel(true_successor()));
1219 }
1220 }
857 } 1221 }
858 1222
859 1223
860 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { 1224 LocationSummary* CurrentContextInstr::MakeLocationSummary() const {
861 UNIMPLEMENTED(); 1225 UNIMPLEMENTED();
862 return NULL; 1226 return NULL;
863 } 1227 }
864 1228
865 1229
866 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1230 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
867 UNIMPLEMENTED(); 1231 UNIMPLEMENTED();
868 } 1232 }
869 1233
870 1234
871 LocationSummary* StrictCompareInstr::MakeLocationSummary() const { 1235 LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
872 UNIMPLEMENTED(); 1236 const intptr_t kNumInputs = 2;
873 return NULL; 1237 const intptr_t kNumTemps = 0;
1238 LocationSummary* locs =
1239 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1240 locs->set_in(0, Location::RegisterOrConstant(left()));
1241 locs->set_in(1, Location::RegisterOrConstant(right()));
1242 locs->set_out(Location::RequiresRegister());
1243 return locs;
874 } 1244 }
875 1245
876 1246
1247 // Special code for numbers (compare values instead of references.)
877 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1248 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
878 UNIMPLEMENTED(); 1249 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1250 Location left = locs()->in(0);
1251 Location right = locs()->in(1);
1252 if (left.IsConstant() && right.IsConstant()) {
1253 // TODO(vegorov): should be eliminated earlier by constant propagation.
1254 const bool result = (kind() == Token::kEQ_STRICT) ?
1255 left.constant().raw() == right.constant().raw() :
1256 left.constant().raw() != right.constant().raw();
1257 __ LoadObject(locs()->out().reg(), result ? Bool::True() : Bool::False());
1258 return;
1259 }
1260 if (left.IsConstant()) {
1261 compiler->EmitEqualityRegConstCompare(right.reg(),
1262 left.constant(),
1263 needs_number_check());
1264 } else if (right.IsConstant()) {
1265 compiler->EmitEqualityRegConstCompare(left.reg(),
1266 right.constant(),
1267 needs_number_check());
1268 } else {
1269 compiler->EmitEqualityRegRegCompare(left.reg(),
1270 right.reg(),
1271 needs_number_check());
1272 }
1273
1274 Register result = locs()->out().reg();
1275 Label load_true, done;
1276 if (kind() == Token::kEQ_STRICT) {
1277 __ beq(CMPRES, ZR, &load_true);
1278 } else {
1279 ASSERT(kind() == Token::kNE_STRICT);
1280 __ bne(CMPRES, ZR, &load_true);
1281 }
1282 __ LoadObject(result, Bool::False());
1283 __ b(&done);
1284 __ Bind(&load_true);
1285 __ LoadObject(result, Bool::True());
1286 __ Bind(&done);
879 } 1287 }
880 1288
881 1289
882 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1290 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
883 BranchInstr* branch) { 1291 BranchInstr* branch) {
884 UNIMPLEMENTED(); 1292 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1293 Location left = locs()->in(0);
1294 Location right = locs()->in(1);
1295 if (left.IsConstant() && right.IsConstant()) {
1296 // TODO(vegorov): should be eliminated earlier by constant propagation.
1297 const bool result = (kind() == Token::kEQ_STRICT) ?
1298 left.constant().raw() == right.constant().raw() :
1299 left.constant().raw() != right.constant().raw();
1300 branch->EmitBranchOnValue(compiler, result);
1301 return;
1302 }
1303 if (left.IsConstant()) {
1304 compiler->EmitEqualityRegConstCompare(right.reg(),
1305 left.constant(),
1306 needs_number_check());
1307 } else if (right.IsConstant()) {
1308 compiler->EmitEqualityRegConstCompare(left.reg(),
1309 right.constant(),
1310 needs_number_check());
1311 } else {
1312 compiler->EmitEqualityRegRegCompare(left.reg(),
1313 right.reg(),
1314 needs_number_check());
1315 }
1316
1317 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
1318 branch->EmitBranchOnCondition(compiler, true_condition);
885 } 1319 }
886 1320
887 1321
888 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1322 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
889 UNIMPLEMENTED(); 1323 UNIMPLEMENTED();
890 } 1324 }
891 1325
892 1326
893 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 1327 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
894 UNIMPLEMENTED(); 1328 UNIMPLEMENTED();
(...skipping 22 matching lines...) Expand all
917 return NULL; 1351 return NULL;
918 } 1352 }
919 1353
920 1354
921 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1355 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
922 UNIMPLEMENTED(); 1356 UNIMPLEMENTED();
923 } 1357 }
924 1358
925 1359
926 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const { 1360 LocationSummary* AllocateObjectInstr::MakeLocationSummary() const {
927 UNIMPLEMENTED(); 1361 return MakeCallSummary();
928 return NULL;
929 } 1362 }
930 1363
931 1364
932 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1365 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
933 UNIMPLEMENTED(); 1366 const Class& cls = Class::ZoneHandle(constructor().Owner());
1367 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
1368 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1369 compiler->GenerateCall(token_pos(),
1370 &label,
1371 PcDescriptors::kOther,
1372 locs());
1373 __ Drop(ArgumentCount()); // Discard arguments.
934 } 1374 }
935 1375
936 1376
937 LocationSummary* CreateClosureInstr::MakeLocationSummary() const { 1377 LocationSummary* CreateClosureInstr::MakeLocationSummary() const {
938 UNIMPLEMENTED(); 1378 UNIMPLEMENTED();
939 return NULL; 1379 return NULL;
940 } 1380 }
941 1381
942 1382
943 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1383 void CreateClosureInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
944 UNIMPLEMENTED(); 1384 UNIMPLEMENTED();
945 } 1385 }
946 1386
947 } // namespace dart 1387 } // namespace dart
948 1388
949 #endif // defined TARGET_ARCH_MIPS 1389 #endif // defined TARGET_ARCH_MIPS
950 1390
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/resolver_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698