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

Side by Side Diff: runtime/vm/flow_graph_compiler_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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 42
43 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, 43 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
44 intptr_t stub_ix) { 44 intptr_t stub_ix) {
45 UNIMPLEMENTED(); 45 UNIMPLEMENTED();
46 } 46 }
47 47
48 48
49 #define __ assembler()-> 49 #define __ assembler()->
50 50
51 51
52 // Fall through if bool_register contains null.
52 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, 53 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
53 Label* is_true, 54 Label* is_true,
54 Label* is_false) { 55 Label* is_false) {
55 UNIMPLEMENTED(); 56 Label fall_through;
57 __ BranchEqual(bool_register, reinterpret_cast<intptr_t>(Object::null()),
58 &fall_through);
59 __ BranchEqual(bool_register, Bool::True(), is_true);
60 __ b(is_false);
61 __ Bind(&fall_through);
56 } 62 }
57 63
58 64
65 // A0: instance (must be preserved).
66 // A1: instantiator type arguments (if used).
59 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( 67 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
60 TypeTestStubKind test_kind, 68 TypeTestStubKind test_kind,
61 Register instance_reg, 69 Register instance_reg,
62 Register type_arguments_reg, 70 Register type_arguments_reg,
63 Register temp_reg, 71 Register temp_reg,
64 Label* is_instance_lbl, 72 Label* is_instance_lbl,
65 Label* is_not_instance_lbl) { 73 Label* is_not_instance_lbl) {
66 UNIMPLEMENTED(); 74 ASSERT(instance_reg == A0);
67 return NULL; 75 ASSERT(temp_reg == kNoRegister); // Unused on MIPS.
76 const SubtypeTestCache& type_test_cache =
77 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
78 __ LoadObject(A2, type_test_cache);
79 if (test_kind == kTestTypeOneArg) {
80 ASSERT(type_arguments_reg == kNoRegister);
81 __ LoadImmediate(A1, reinterpret_cast<intptr_t>(Object::null()));
82 __ BranchLink(&StubCode::Subtype1TestCacheLabel());
83 } else if (test_kind == kTestTypeTwoArgs) {
84 ASSERT(type_arguments_reg == kNoRegister);
85 __ LoadImmediate(A1, reinterpret_cast<intptr_t>(Object::null()));
86 __ BranchLink(&StubCode::Subtype2TestCacheLabel());
87 } else if (test_kind == kTestTypeThreeArgs) {
88 ASSERT(type_arguments_reg == A1);
89 __ BranchLink(&StubCode::Subtype3TestCacheLabel());
90 } else {
91 UNREACHABLE();
92 }
93 // Result is in V0: null -> not found, otherwise Bool::True or Bool::False.
94 GenerateBoolToJump(V0, is_instance_lbl, is_not_instance_lbl);
95 return type_test_cache.raw();
68 } 96 }
69 97
70 98
71 RawSubtypeTestCache* 99 RawSubtypeTestCache*
72 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( 100 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
73 intptr_t token_pos, 101 intptr_t token_pos,
74 const AbstractType& type, 102 const AbstractType& type,
75 Label* is_instance_lbl, 103 Label* is_instance_lbl,
76 Label* is_not_instance_lbl) { 104 Label* is_not_instance_lbl) {
77 UNIMPLEMENTED(); 105 UNIMPLEMENTED();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 } 174 }
147 if (type.IsStringType()) { 175 if (type.IsStringType()) {
148 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); 176 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
149 return false; 177 return false;
150 } 178 }
151 // Otherwise fallthrough. 179 // Otherwise fallthrough.
152 return true; 180 return true;
153 } 181 }
154 182
155 183
184 // Uses SubtypeTestCache to store instance class and result.
185 // A0: instance to test.
186 // Clobbers A1, A2, T0-T3.
187 // Immediate class test already done.
188 // TODO(srdjan): Implement a quicker subtype check, as type test
189 // arrays can grow too high, but they may be useful when optimizing
190 // code (type-feedback).
156 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( 191 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
157 intptr_t token_pos, 192 intptr_t token_pos,
158 const Class& type_class, 193 const Class& type_class,
159 Label* is_instance_lbl, 194 Label* is_instance_lbl,
160 Label* is_not_instance_lbl) { 195 Label* is_not_instance_lbl) {
161 UNIMPLEMENTED(); 196 __ Comment("Subtype1TestCacheLookup");
162 return NULL; 197 const Register kInstanceReg = A0;
198 __ LoadClass(T0, kInstanceReg);
199 // T1: instance class.
200 // Check immediate superclass equality.
201 __ lw(T0, FieldAddress(T0, Class::super_type_offset()));
202 __ lw(T0, FieldAddress(T0, Type::type_class_offset()));
203 __ BranchEqual(T0, type_class, is_instance_lbl);
204
205 const Register kTypeArgumentsReg = kNoRegister;
206 const Register kTempReg = kNoRegister;
207 return GenerateCallSubtypeTestStub(kTestTypeOneArg,
208 kInstanceReg,
209 kTypeArgumentsReg,
210 kTempReg,
211 is_instance_lbl,
212 is_not_instance_lbl);
163 } 213 }
164 214
165 215
166 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( 216 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
167 intptr_t token_pos, 217 intptr_t token_pos,
168 const AbstractType& type, 218 const AbstractType& type,
169 Label* is_instance_lbl, 219 Label* is_instance_lbl,
170 Label* is_not_instance_lbl) { 220 Label* is_not_instance_lbl) {
171 UNIMPLEMENTED(); 221 UNIMPLEMENTED();
172 return NULL; 222 return NULL;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 __ lw(A2, Address(SP, 1 * kWordSize)); 372 __ lw(A2, Address(SP, 1 * kWordSize));
323 __ addiu(SP, SP, Immediate(2 * kWordSize)); 373 __ addiu(SP, SP, Immediate(2 * kWordSize));
324 __ PushObject(Object::ZoneHandle()); // Make room for the result. 374 __ PushObject(Object::ZoneHandle()); // Make room for the result.
325 __ Push(A0); // Push the source object. 375 __ Push(A0); // Push the source object.
326 __ PushObject(dst_type); // Push the type of the destination. 376 __ PushObject(dst_type); // Push the type of the destination.
327 // Push instantiator and its type arguments. 377 // Push instantiator and its type arguments.
328 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 378 __ addiu(SP, SP, Immediate(-2 * kWordSize));
329 __ sw(A2, Address(SP, 1 * kWordSize)); 379 __ sw(A2, Address(SP, 1 * kWordSize));
330 __ sw(A1, Address(SP, 0 * kWordSize)); 380 __ sw(A1, Address(SP, 0 * kWordSize));
331 __ PushObject(dst_name); // Push the name of the destination. 381 __ PushObject(dst_name); // Push the name of the destination.
332 __ LoadObject(A0, test_cache); 382 __ LoadObject(T0, test_cache);
333 __ Push(A0); 383 __ Push(T0);
334 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs); 384 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
335 // Pop the parameters supplied to the runtime entry. The result of the 385 // Pop the parameters supplied to the runtime entry. The result of the
336 // type check runtime call is the checked value. 386 // type check runtime call is the checked value.
337 __ Drop(6); 387 __ Drop(6);
338 __ Pop(A0); 388 __ Pop(A0);
339 389
340 __ Bind(&is_assignable); 390 __ Bind(&is_assignable);
341 // Restore instantiator and its type arguments. 391 // Restore instantiator and its type arguments.
342 __ lw(A1, Address(SP, 0 * kWordSize)); 392 __ lw(A1, Address(SP, 0 * kWordSize));
343 __ lw(A2, Address(SP, 1 * kWordSize)); 393 __ lw(A2, Address(SP, 1 * kWordSize));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 // Argument i passed at fp[kLastParamSlotIndex + num_args - 1 - i] is copied 448 // Argument i passed at fp[kLastParamSlotIndex + num_args - 1 - i] is copied
399 // to fp[kFirstLocalSlotIndex - i]. 449 // to fp[kFirstLocalSlotIndex - i].
400 450
401 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 451 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
402 // Since T1 and T2 are Smi, use sll 1 instead of sll 2. 452 // Since T1 and T2 are Smi, use sll 1 instead of sll 2.
403 // Let T1 point to the last passed positional argument, i.e. to 453 // Let T1 point to the last passed positional argument, i.e. to
404 // fp[kLastParamSlotIndex + num_args - 1 - (num_pos_args - 1)]. 454 // fp[kLastParamSlotIndex + num_args - 1 - (num_pos_args - 1)].
405 __ subu(T1, T1, T2); 455 __ subu(T1, T1, T2);
406 __ sll(T1, T1, 1); 456 __ sll(T1, T1, 1);
407 __ addu(T1, FP, T1); 457 __ addu(T1, FP, T1);
408 __ addiu(T1, T1, Immediate(kLastParamSlotIndex * kWordSize)); 458 __ AddImmediate(T1, kLastParamSlotIndex * kWordSize);
409 459
410 // Let T0 point to the last copied positional argument, i.e. to 460 // Let T0 point to the last copied positional argument, i.e. to
411 // fp[kFirstLocalSlotIndex - (num_pos_args - 1)]. 461 // fp[kFirstLocalSlotIndex - (num_pos_args - 1)].
412 __ addiu(T0, FP, Immediate((kFirstLocalSlotIndex + 1) * kWordSize)); 462 __ AddImmediate(T0, FP, (kFirstLocalSlotIndex + 1) * kWordSize);
413 __ sll(T3, T2, 1); // T2 is a Smi. 463 __ sll(T3, T2, 1); // T2 is a Smi.
414 __ subu(T0, T0, T3); 464 __ subu(T0, T0, T3);
415 465
416 Label loop, loop_condition; 466 Label loop, loop_condition;
417 __ b(&loop_condition); 467 __ b(&loop_condition);
418 __ delay_slot()->SmiUntag(T2); 468 __ delay_slot()->SmiUntag(T2);
419 // We do not use the final allocation index of the variable here, i.e. 469 // We do not use the final allocation index of the variable here, i.e.
420 // scope->VariableAt(i)->index(), because captured variables still need 470 // scope->VariableAt(i)->index(), because captured variables still need
421 // to be copied to the context that is not yet allocated. 471 // to be copied to the context that is not yet allocated.
422 __ Bind(&loop); 472 __ Bind(&loop);
(...skipping 27 matching lines...) Expand all
450 opt_param_position[i + 1] = pos; 500 opt_param_position[i + 1] = pos;
451 } 501 }
452 // Generate code handling each optional parameter in alphabetical order. 502 // Generate code handling each optional parameter in alphabetical order.
453 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 503 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
454 __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::positional_count_offset())); 504 __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::positional_count_offset()));
455 __ SmiUntag(T2); 505 __ SmiUntag(T2);
456 // Let T1 point to the first passed argument, i.e. to 506 // Let T1 point to the first passed argument, i.e. to
457 // fp[kLastParamSlotIndex + num_args - 1 - 0]; num_args (T1) is Smi. 507 // fp[kLastParamSlotIndex + num_args - 1 - 0]; num_args (T1) is Smi.
458 __ sll(T3, T1, 1); 508 __ sll(T3, T1, 1);
459 __ addu(T1, FP, T3); 509 __ addu(T1, FP, T3);
460 __ addiu(T1, T1, Immediate((kLastParamSlotIndex - 1) * kWordSize)); 510 __ AddImmediate(T1, (kLastParamSlotIndex - 1) * kWordSize);
461 // Let T0 point to the entry of the first named argument. 511 // Let T0 point to the entry of the first named argument.
462 __ addiu(T0, S4, Immediate( 512 __ AddImmediate(T0, S4,
463 ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag)); 513 ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag);
464 for (int i = 0; i < num_opt_named_params; i++) { 514 for (int i = 0; i < num_opt_named_params; i++) {
465 Label load_default_value, assign_optional_parameter; 515 Label load_default_value, assign_optional_parameter;
466 const int param_pos = opt_param_position[i]; 516 const int param_pos = opt_param_position[i];
467 // Check if this named parameter was passed in. 517 // Check if this named parameter was passed in.
468 // Load T3 with the name of the argument. 518 // Load T3 with the name of the argument.
469 __ lw(T3, Address(T0, ArgumentsDescriptor::name_offset())); 519 __ lw(T3, Address(T0, ArgumentsDescriptor::name_offset()));
470 ASSERT(opt_param[i]->name().IsSymbol()); 520 ASSERT(opt_param[i]->name().IsSymbol());
471 __ BranchNotEqual(T3, opt_param[i]->name(), &load_default_value); 521 __ BranchNotEqual(T3, opt_param[i]->name(), &load_default_value);
472 522
473 // Load T3 with passed-in argument at provided arg_pos, i.e. at 523 // Load T3 with passed-in argument at provided arg_pos, i.e. at
474 // fp[kLastParamSlotIndex + num_args - 1 - arg_pos]. 524 // fp[kLastParamSlotIndex + num_args - 1 - arg_pos].
475 __ lw(T3, Address(T0, ArgumentsDescriptor::position_offset())); 525 __ lw(T3, Address(T0, ArgumentsDescriptor::position_offset()));
476 // T3 is arg_pos as Smi. 526 // T3 is arg_pos as Smi.
477 // Point to next named entry. 527 // Point to next named entry.
478 __ addiu(T0, T0, Immediate(ArgumentsDescriptor::named_entry_size())); 528 __ AddImmediate(T0, ArgumentsDescriptor::named_entry_size());
479 __ subu(T3, ZR, T3); 529 __ subu(T3, ZR, T3);
480 __ sll(T3, T3, 1); 530 __ sll(T3, T3, 1);
481 __ addu(T3, T1, T3); 531 __ addu(T3, T1, T3);
482 __ b(&assign_optional_parameter); 532 __ b(&assign_optional_parameter);
483 __ delay_slot()->lw(T3, Address(T3)); 533 __ delay_slot()->lw(T3, Address(T3));
484 534
485 __ Bind(&load_default_value); 535 __ Bind(&load_default_value);
486 // Load T3 with default argument. 536 // Load T3 with default argument.
487 const Object& value = Object::ZoneHandle( 537 const Object& value = Object::ZoneHandle(
488 parsed_function().default_parameter_values().At( 538 parsed_function().default_parameter_values().At(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 __ SmiUntag(T1); 580 __ SmiUntag(T1);
531 // Check that T2 equals T1, i.e. no named arguments passed. 581 // Check that T2 equals T1, i.e. no named arguments passed.
532 __ beq(T2, T1, &all_arguments_processed); 582 __ beq(T2, T1, &all_arguments_processed);
533 } 583 }
534 584
535 __ Bind(&wrong_num_arguments); 585 __ Bind(&wrong_num_arguments);
536 if (StackSize() != 0) { 586 if (StackSize() != 0) {
537 // We need to unwind the space we reserved for locals and copied parameters. 587 // We need to unwind the space we reserved for locals and copied parameters.
538 // The NoSuchMethodFunction stub does not expect to see that area on the 588 // The NoSuchMethodFunction stub does not expect to see that area on the
539 // stack. 589 // stack.
540 __ addiu(SP, SP, Immediate(StackSize() * kWordSize)); 590 __ AddImmediate(SP, StackSize() * kWordSize);
541 } 591 }
542 // The call below has an empty stackmap because we have just 592 // The call below has an empty stackmap because we have just
543 // dropped the spill slots. 593 // dropped the spill slots.
544 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); 594 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
545 595
546 // Invoke noSuchMethod function passing the original name of the function. 596 // Invoke noSuchMethod function passing the original name of the function.
547 // If the function is a closure function, use "call" as the original name. 597 // If the function is a closure function, use "call" as the original name.
548 const String& name = String::Handle( 598 const String& name = String::Handle(
549 function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); 599 function.IsClosureFunction() ? Symbols::Call().raw() : function.name());
550 const int kNumArgsChecked = 1; 600 const int kNumArgsChecked = 1;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 773
724 __ lw(T1, FieldAddress(S4, 774 __ lw(T1, FieldAddress(S4,
725 ArgumentsDescriptor::positional_count_offset())); 775 ArgumentsDescriptor::positional_count_offset()));
726 __ beq(T0, T1, &correct_num_arguments); 776 __ beq(T0, T1, &correct_num_arguments);
727 __ Bind(&wrong_num_arguments); 777 __ Bind(&wrong_num_arguments);
728 if (function.IsClosureFunction()) { 778 if (function.IsClosureFunction()) {
729 if (StackSize() != 0) { 779 if (StackSize() != 0) {
730 // We need to unwind the space we reserved for locals and copied 780 // We need to unwind the space we reserved for locals and copied
731 // parameters. The NoSuchMethodFunction stub does not expect to see 781 // parameters. The NoSuchMethodFunction stub does not expect to see
732 // that area on the stack. 782 // that area on the stack.
733 __ addiu(SP, SP, Immediate(StackSize() * kWordSize)); 783 __ AddImmediate(SP, StackSize() * kWordSize);
734 } 784 }
735 // The call below has an empty stackmap because we have just 785 // The call below has an empty stackmap because we have just
736 // dropped the spill slots. 786 // dropped the spill slots.
737 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); 787 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
738 788
739 // Invoke noSuchMethod function passing "call" as the function name. 789 // Invoke noSuchMethod function passing "call" as the function name.
740 const int kNumArgsChecked = 1; 790 const int kNumArgsChecked = 1;
741 const ICData& ic_data = ICData::ZoneHandle( 791 const ICData& ic_data = ICData::ZoneHandle(
742 ICData::New(function, Symbols::Call(), 792 ICData::New(function, Symbols::Call(),
743 Isolate::kNoDeoptId, kNumArgsChecked)); 793 Isolate::kNoDeoptId, kNumArgsChecked));
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 deopt_id, 901 deopt_id,
852 token_pos); 902 token_pos);
853 } 903 }
854 } 904 }
855 905
856 906
857 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, 907 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
858 intptr_t deopt_id, 908 intptr_t deopt_id,
859 const RuntimeEntry& entry, 909 const RuntimeEntry& entry,
860 LocationSummary* locs) { 910 LocationSummary* locs) {
861 __ Unimplemented("call runtime"); 911 __ CallRuntime(entry);
912 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
913 RecordSafepoint(locs);
914 if (deopt_id != Isolate::kNoDeoptId) {
915 // Marks either the continuation point in unoptimized code or the
916 // deoptimization point in optimized code, after call.
917 if (is_optimizing()) {
918 AddDeoptIndexAtCall(deopt_id, token_pos);
919 } else {
920 // Add deoptimization continuation point after the call and before the
921 // arguments are removed.
922 AddCurrentDescriptor(PcDescriptors::kDeoptAfter,
923 deopt_id,
924 token_pos);
925 }
926 }
862 } 927 }
863 928
864 929
865 void FlowGraphCompiler::EmitOptimizedInstanceCall( 930 void FlowGraphCompiler::EmitOptimizedInstanceCall(
866 ExternalLabel* target_label, 931 ExternalLabel* target_label,
867 const ICData& ic_data, 932 const ICData& ic_data,
868 const Array& arguments_descriptor, 933 const Array& arguments_descriptor,
869 intptr_t argument_count, 934 intptr_t argument_count,
870 intptr_t deopt_id, 935 intptr_t deopt_id,
871 intptr_t token_pos, 936 intptr_t token_pos,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg, 990 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
926 const Object& obj, 991 const Object& obj,
927 bool needs_number_check) { 992 bool needs_number_check) {
928 UNIMPLEMENTED(); 993 UNIMPLEMENTED();
929 } 994 }
930 995
931 996
932 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 997 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
933 Register right, 998 Register right,
934 bool needs_number_check) { 999 bool needs_number_check) {
935 UNIMPLEMENTED(); 1000 if (needs_number_check) {
1001 __ Push(left);
1002 __ Push(right);
1003 __ BranchLink(&StubCode::IdenticalWithNumberCheckLabel());
1004 // Stub returns result in CMPRES. If it is 0, then left and right are equal.
1005 __ Pop(right);
1006 __ Pop(left);
1007 } else {
1008 __ subu(CMPRES, left, right);
1009 }
936 } 1010 }
937 1011
938 1012
939 void FlowGraphCompiler::EmitSuperEqualityCallPrologue(Register result, 1013 void FlowGraphCompiler::EmitSuperEqualityCallPrologue(Register result,
940 Label* skip_call) { 1014 Label* skip_call) {
941 UNIMPLEMENTED(); 1015 UNIMPLEMENTED();
942 } 1016 }
943 1017
944 1018
945 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { 1019 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 1190
1117 1191
1118 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1192 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1119 UNIMPLEMENTED(); 1193 UNIMPLEMENTED();
1120 } 1194 }
1121 1195
1122 1196
1123 } // namespace dart 1197 } // namespace dart
1124 1198
1125 #endif // defined TARGET_ARCH_MIPS 1199 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698