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

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

Issue 20369003: Implements far branch targets for MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 __ addu(T1, FP, T1); 293 __ addu(T1, FP, T1);
294 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize); 294 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize);
295 // T1: address of first argument on stack. 295 // T1: address of first argument on stack.
296 // T2: address of first argument in array. 296 // T2: address of first argument in array.
297 297
298 Label loop, loop_exit; 298 Label loop, loop_exit;
299 __ blez(A1, &loop_exit); 299 __ blez(A1, &loop_exit);
300 __ delay_slot()->addiu(T2, V0, 300 __ delay_slot()->addiu(T2, V0,
301 Immediate(Array::data_offset() - kHeapObjectTag)); 301 Immediate(Array::data_offset() - kHeapObjectTag));
302 __ Bind(&loop); 302 __ Bind(&loop);
303 __ lw(TMP, Address(T1)); 303 __ lw(T3, Address(T1));
304 __ addiu(A1, A1, Immediate(-Smi::RawValue(1))); 304 __ addiu(A1, A1, Immediate(-Smi::RawValue(1)));
305 __ addiu(T1, T1, Immediate(-kWordSize)); 305 __ addiu(T1, T1, Immediate(-kWordSize));
306 __ addiu(T2, T2, Immediate(kWordSize)); 306 __ addiu(T2, T2, Immediate(kWordSize));
307 __ bgez(A1, &loop); 307 __ bgez(A1, &loop);
308 __ delay_slot()->sw(TMP, Address(T2, -kWordSize)); 308 __ delay_slot()->sw(T3, Address(T2, -kWordSize));
309 __ Bind(&loop_exit); 309 __ Bind(&loop_exit);
310 } 310 }
311 311
312 312
313 // Input parameters: 313 // Input parameters:
314 // S5: ic-data. 314 // S5: ic-data.
315 // S4: arguments descriptor array. 315 // S4: arguments descriptor array.
316 // Note: The receiver object is the first argument to the function being 316 // Note: The receiver object is the first argument to the function being
317 // called, the stub accesses the receiver from this location directly 317 // called, the stub accesses the receiver from this location directly
318 // when trying to resolve the call. 318 // when trying to resolve the call.
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 __ and_(T3, T3, TMP1); 582 __ and_(T3, T3, TMP1);
583 __ addu(T2, T3, V0); 583 __ addu(T2, T3, V0);
584 584
585 // Check if the allocation fits into the remaining space. 585 // Check if the allocation fits into the remaining space.
586 // V0: potential new object start. 586 // V0: potential new object start.
587 // A0: array element type. 587 // A0: array element type.
588 // A1: array length as Smi. 588 // A1: array length as Smi.
589 // T0: points to new space object. 589 // T0: points to new space object.
590 // T2: potential next object start. 590 // T2: potential next object start.
591 // T3: array size. 591 // T3: array size.
592 __ lw(TMP1, Address(T0, Scavenger::end_offset())); 592 __ lw(CMPRES1, Address(T0, Scavenger::end_offset()));
593 __ BranchUnsignedGreaterEqual(T2, TMP1, &slow_case); 593 __ BranchUnsignedGreaterEqual(T2, CMPRES1, &slow_case);
594 594
595 // Successfully allocated the object(s), now update top to point to 595 // Successfully allocated the object(s), now update top to point to
596 // next object start and initialize the object. 596 // next object start and initialize the object.
597 // V0: potential new object start. 597 // V0: potential new object start.
598 // T2: potential next object start. 598 // T2: potential next object start.
599 // T0: Points to new space object. 599 // T0: Points to new space object.
600 __ sw(T2, Address(T0, Scavenger::top_offset())); 600 __ sw(T2, Address(T0, Scavenger::top_offset()));
601 __ addiu(V0, V0, Immediate(kHeapObjectTag)); 601 __ addiu(V0, V0, Immediate(kHeapObjectTag));
602 602
603 // V0: new object start as a tagged pointer. 603 // V0: new object start as a tagged pointer.
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 __ LoadImmediate(T5, heap->TopAddress()); 946 __ LoadImmediate(T5, heap->TopAddress());
947 __ lw(V0, Address(T5, 0)); 947 __ lw(V0, Address(T5, 0));
948 __ addu(T3, T2, V0); 948 __ addu(T3, T2, V0);
949 949
950 // Check if the allocation fits into the remaining space. 950 // Check if the allocation fits into the remaining space.
951 // V0: potential new object. 951 // V0: potential new object.
952 // T1: number of context variables. 952 // T1: number of context variables.
953 // T2: object size. 953 // T2: object size.
954 // T3: potential next object start. 954 // T3: potential next object start.
955 __ LoadImmediate(TMP1, heap->EndAddress()); 955 __ LoadImmediate(TMP1, heap->EndAddress());
956 __ lw(TMP1, Address(TMP1, 0)); 956 __ lw(CMPRES1, Address(TMP1, 0));
957 if (FLAG_use_slow_path) { 957 if (FLAG_use_slow_path) {
958 __ b(&slow_case); 958 __ b(&slow_case);
959 } else { 959 } else {
960 __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case); 960 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
961 } 961 }
962 962
963 // Successfully allocated the object, now update top to point to 963 // Successfully allocated the object, now update top to point to
964 // next object start and initialize the object. 964 // next object start and initialize the object.
965 // V0: new object. 965 // V0: new object.
966 // T1: number of context variables. 966 // T1: number of context variables.
967 // T2: object size. 967 // T2: object size.
968 // T3: next object start. 968 // T3: next object start.
969 __ sw(T3, Address(T5, 0)); 969 __ sw(T3, Address(T5, 0));
970 __ addiu(V0, V0, Immediate(kHeapObjectTag)); 970 __ addiu(V0, V0, Immediate(kHeapObjectTag));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 // V0: new object. 1005 // V0: new object.
1006 // T1: number of context variables. 1006 // T1: number of context variables.
1007 Label loop, loop_exit; 1007 Label loop, loop_exit;
1008 __ blez(T1, &loop_exit); 1008 __ blez(T1, &loop_exit);
1009 // Setup the parent field. 1009 // Setup the parent field.
1010 __ delay_slot()->sw(T7, FieldAddress(V0, Context::parent_offset())); 1010 __ delay_slot()->sw(T7, FieldAddress(V0, Context::parent_offset()));
1011 __ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag); 1011 __ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag);
1012 __ sll(T1, T1, 2); 1012 __ sll(T1, T1, 2);
1013 __ Bind(&loop); 1013 __ Bind(&loop);
1014 __ addiu(T1, T1, Immediate(-kWordSize)); 1014 __ addiu(T1, T1, Immediate(-kWordSize));
1015 __ addu(TMP1, T3, T1); 1015 __ addu(T4, T3, T1);
1016 __ bgtz(T1, &loop); 1016 __ bgtz(T1, &loop);
1017 __ delay_slot()->sw(T7, Address(TMP1)); 1017 __ delay_slot()->sw(T7, Address(T4));
1018 __ Bind(&loop_exit); 1018 __ Bind(&loop_exit);
1019 1019
1020 // Done allocating and initializing the context. 1020 // Done allocating and initializing the context.
1021 // V0: new object. 1021 // V0: new object.
1022 __ Ret(); 1022 __ Ret();
1023 1023
1024 __ Bind(&slow_case); 1024 __ Bind(&slow_case);
1025 } 1025 }
1026 // Create a stub frame as we are pushing some objects on the stack before 1026 // Create a stub frame as we are pushing some objects on the stack before
1027 // calling into the runtime. 1027 // calling into the runtime.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 __ delay_slot()->mov(T4, T3); 1154 __ delay_slot()->mov(T4, T3);
1155 __ AddImmediate(T3, type_args_size); 1155 __ AddImmediate(T3, type_args_size);
1156 __ Bind(&no_instantiator); 1156 __ Bind(&no_instantiator);
1157 // T4: potential new object end and, if T4 != T3, potential new 1157 // T4: potential new object end and, if T4 != T3, potential new
1158 // InstantiatedTypeArguments object start. 1158 // InstantiatedTypeArguments object start.
1159 } 1159 }
1160 // Check if the allocation fits into the remaining space. 1160 // Check if the allocation fits into the remaining space.
1161 // T2: potential new object start. 1161 // T2: potential new object start.
1162 // T3: potential next object start. 1162 // T3: potential next object start.
1163 __ LoadImmediate(TMP1, heap->EndAddress()); 1163 __ LoadImmediate(TMP1, heap->EndAddress());
1164 __ lw(TMP1, Address(TMP1)); 1164 __ lw(CMPRES1, Address(TMP1));
1165 if (FLAG_use_slow_path) { 1165 if (FLAG_use_slow_path) {
1166 __ b(&slow_case); 1166 __ b(&slow_case);
1167 } else { 1167 } else {
1168 __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case); 1168 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
1169 } 1169 }
1170 1170
1171 // Successfully allocated the object(s), now update top to point to 1171 // Successfully allocated the object(s), now update top to point to
1172 // next object start and initialize the object. 1172 // next object start and initialize the object.
1173 __ sw(T3, Address(T5)); 1173 __ sw(T3, Address(T5));
1174 1174
1175 if (is_cls_parameterized) { 1175 if (is_cls_parameterized) {
1176 // Initialize the type arguments field in the object. 1176 // Initialize the type arguments field in the object.
1177 // T2: new object start. 1177 // T2: new object start.
1178 // T4: potential new object end and, if T4 != T3, potential new 1178 // T4: potential new object end and, if T4 != T3, potential new
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 __ AddImmediate(T3, T2, closure_size); 1322 __ AddImmediate(T3, T2, closure_size);
1323 if (is_implicit_instance_closure) { 1323 if (is_implicit_instance_closure) {
1324 __ mov(T4, T3); // T4: new context address. 1324 __ mov(T4, T3); // T4: new context address.
1325 __ AddImmediate(T3, context_size); 1325 __ AddImmediate(T3, context_size);
1326 } 1326 }
1327 // Check if the allocation fits into the remaining space. 1327 // Check if the allocation fits into the remaining space.
1328 // T2: potential new closure object. 1328 // T2: potential new closure object.
1329 // T3: address of top of heap. 1329 // T3: address of top of heap.
1330 // T4: potential new context object (only if is_implicit_closure). 1330 // T4: potential new context object (only if is_implicit_closure).
1331 __ LoadImmediate(TMP1, heap->EndAddress()); 1331 __ LoadImmediate(TMP1, heap->EndAddress());
1332 __ lw(TMP1, Address(TMP1)); 1332 __ lw(CMPRES1, Address(TMP1));
1333 if (FLAG_use_slow_path) { 1333 if (FLAG_use_slow_path) {
1334 __ b(&slow_case); 1334 __ b(&slow_case);
1335 } else { 1335 } else {
1336 __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case); 1336 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
1337 } 1337 }
1338 1338
1339 // Successfully allocated the object, now update top to point to 1339 // Successfully allocated the object, now update top to point to
1340 // next object start and initialize the object. 1340 // next object start and initialize the object.
1341 __ sw(T3, Address(T5)); 1341 __ sw(T3, Address(T5));
1342 1342
1343 // T2: new closure object. 1343 // T2: new closure object.
1344 // T4: new context object (only if is_implicit_closure). 1344 // T4: new context object (only if is_implicit_closure).
1345 // Set the tags. 1345 // Set the tags.
1346 uword tags = 0; 1346 uword tags = 0;
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 // and the arguments descriptor array. 1681 // and the arguments descriptor array.
1682 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); 1682 __ addiu(SP, SP, Immediate(num_slots * kWordSize));
1683 __ LeaveStubFrame(); 1683 __ LeaveStubFrame();
1684 Label call_target_function; 1684 Label call_target_function;
1685 __ BranchNotEqual(T3, reinterpret_cast<int32_t>(Object::null()), 1685 __ BranchNotEqual(T3, reinterpret_cast<int32_t>(Object::null()),
1686 &call_target_function); 1686 &call_target_function);
1687 1687
1688 // NoSuchMethod or closure. 1688 // NoSuchMethod or closure.
1689 // Mark IC call that it may be a closure call that does not collect 1689 // Mark IC call that it may be a closure call that does not collect
1690 // type feedback. 1690 // type feedback.
1691 __ LoadImmediate(TMP1, 1); 1691 __ LoadImmediate(T6, 1);
1692 __ Branch(&StubCode::InstanceFunctionLookupLabel()); 1692 __ Branch(&StubCode::InstanceFunctionLookupLabel());
1693 __ delay_slot()->sb(TMP1, FieldAddress(S5, ICData::is_closure_call_offset())); 1693 __ delay_slot()->sb(T6, FieldAddress(S5, ICData::is_closure_call_offset()));
1694 1694
1695 __ Bind(&found); 1695 __ Bind(&found);
1696 // T0: Pointer to an IC data check group. 1696 // T0: Pointer to an IC data check group.
1697 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1697 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1698 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1698 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1699 __ lw(T3, Address(T0, target_offset)); 1699 __ lw(T3, Address(T0, target_offset));
1700 __ lw(T4, Address(T0, count_offset)); 1700 __ lw(T4, Address(T0, count_offset));
1701 1701
1702 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); 1702 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
1703 1703
1704 __ bgez(T5, &call_target_function); // No overflow. 1704 __ bgez(T5, &call_target_function); // No overflow.
1705 __ delay_slot()->sw(T4, Address(T0, count_offset)); 1705 __ delay_slot()->sw(T4, Address(T0, count_offset));
1706 1706
1707 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1707 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1708 __ sw(T1, Address(T0, count_offset)); 1708 __ sw(T1, Address(T0, count_offset));
1709 1709
1710 __ Bind(&call_target_function); 1710 __ Bind(&call_target_function);
1711 // T3: Target function. 1711 // T3: Target function.
1712 __ lw(T3, FieldAddress(T3, Function::code_offset())); 1712 __ lw(T3, FieldAddress(T3, Function::code_offset()));
1713 __ lw(T3, FieldAddress(T3, Code::instructions_offset())); 1713 __ lw(T3, FieldAddress(T3, Code::instructions_offset()));
1714 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag); 1714 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
1715 __ jr(T3); 1715 __ jr(T3);
1716 1716
1717 // Instance in T3, return its class-id in T3 as Smi. 1717 // Instance in T3, return its class-id in T3 as Smi.
1718 __ Bind(&get_class_id_as_smi); 1718 __ Bind(&get_class_id_as_smi);
1719 Label not_smi; 1719 Label not_smi;
1720 // Test if Smi -> load Smi class for comparison. 1720 // Test if Smi -> load Smi class for comparison.
1721 __ andi(TMP1, T3, Immediate(kSmiTagMask)); 1721 __ andi(CMPRES1, T3, Immediate(kSmiTagMask));
1722 __ bne(TMP1, ZR, &not_smi); 1722 __ bne(CMPRES1, ZR, &not_smi);
1723 __ jr(RA); 1723 __ jr(RA);
1724 __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid))); 1724 __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
1725 1725
1726 __ Bind(&not_smi); 1726 __ Bind(&not_smi);
1727 __ LoadClassId(T3, T3); 1727 __ LoadClassId(T3, T3);
1728 __ jr(RA); 1728 __ jr(RA);
1729 __ delay_slot()->SmiTag(T3); 1729 __ delay_slot()->SmiTag(T3);
1730 } 1730 }
1731 1731
1732 1732
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 1847
1848 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); 1848 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue));
1849 __ sw(T1, Address(T0, count_offset)); 1849 __ sw(T1, Address(T0, count_offset));
1850 1850
1851 __ Bind(&increment_done); 1851 __ Bind(&increment_done);
1852 1852
1853 Label target_is_compiled; 1853 Label target_is_compiled;
1854 // Get function and call it, if possible. 1854 // Get function and call it, if possible.
1855 __ lw(T3, Address(T0, target_offset)); 1855 __ lw(T3, Address(T0, target_offset));
1856 __ lw(T4, FieldAddress(T3, Function::code_offset())); 1856 __ lw(T4, FieldAddress(T3, Function::code_offset()));
1857 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 1857 __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null()));
1858 __ bne(T4, TMP, &target_is_compiled); 1858 __ bne(T4, CMPRES1, &target_is_compiled);
1859 1859
1860 __ EnterStubFrame(); 1860 __ EnterStubFrame();
1861 // Preserve target function and IC data object. 1861 // Preserve target function and IC data object.
1862 // Two preserved registers, one argument (function) => 3 slots. 1862 // Two preserved registers, one argument (function) => 3 slots.
1863 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1863 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1864 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data. 1864 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data.
1865 __ sw(T3, Address(SP, 1 * kWordSize)); // Preserve function. 1865 __ sw(T3, Address(SP, 1 * kWordSize)); // Preserve function.
1866 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument. 1866 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument.
1867 __ CallRuntime(kCompileFunctionRuntimeEntry); 1867 __ CallRuntime(kCompileFunctionRuntimeEntry);
1868 __ lw(T3, Address(SP, 1 * kWordSize)); // Restore function. 1868 __ lw(T3, Address(SP, 1 * kWordSize)); // Restore function.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 // Create a stub frame as we are pushing some objects on the stack before 1947 // Create a stub frame as we are pushing some objects on the stack before
1948 // calling into the runtime. 1948 // calling into the runtime.
1949 __ TraceSimMsg("BreakpointDynamicStub"); 1949 __ TraceSimMsg("BreakpointDynamicStub");
1950 __ EnterStubFrame(); 1950 __ EnterStubFrame();
1951 __ Push(S5); 1951 __ Push(S5);
1952 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1952 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1953 __ Pop(S5); 1953 __ Pop(S5);
1954 __ LeaveStubFrame(); 1954 __ LeaveStubFrame();
1955 1955
1956 // Find out which dispatch stub to call. 1956 // Find out which dispatch stub to call.
1957 __ lw(TMP1, FieldAddress(S5, ICData::num_args_tested_offset())); 1957 __ lw(T1, FieldAddress(S5, ICData::num_args_tested_offset()));
1958 1958
1959 Label one_arg, two_args, three_args; 1959 Label one_arg, two_args, three_args;
1960 __ BranchEqual(TMP1, 1, &one_arg); 1960 __ BranchEqual(T1, 1, &one_arg);
1961 __ BranchEqual(TMP1, 2, &two_args); 1961 __ BranchEqual(T1, 2, &two_args);
1962 __ BranchEqual(TMP1, 3, &three_args); 1962 __ BranchEqual(T1, 3, &three_args);
1963 __ Stop("Unsupported number of arguments tested."); 1963 __ Stop("Unsupported number of arguments tested.");
1964 1964
1965 __ Bind(&one_arg); 1965 __ Bind(&one_arg);
1966 __ Branch(&StubCode::OneArgCheckInlineCacheLabel()); 1966 __ Branch(&StubCode::OneArgCheckInlineCacheLabel());
1967 __ Bind(&two_args); 1967 __ Bind(&two_args);
1968 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel()); 1968 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel());
1969 __ Bind(&three_args); 1969 __ Bind(&three_args);
1970 __ Branch(&StubCode::ThreeArgsCheckInlineCacheLabel()); 1970 __ Branch(&StubCode::ThreeArgsCheckInlineCacheLabel());
1971 __ break_(0); 1971 __ break_(0);
1972 } 1972 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 // T0: ICData. 2114 // T0: ICData.
2115 // V0: result. 2115 // V0: result.
2116 // TODO(srdjan): Move to VM stubs once Boolean objects become VM objects. 2116 // TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
2117 void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) { 2117 void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
2118 __ TraceSimMsg("EqualityWithNullArgStub"); 2118 __ TraceSimMsg("EqualityWithNullArgStub");
2119 __ Comment("EqualityWithNullArgStub"); 2119 __ Comment("EqualityWithNullArgStub");
2120 __ EnterStubFrame(); 2120 __ EnterStubFrame();
2121 static const intptr_t kNumArgsTested = 2; 2121 static const intptr_t kNumArgsTested = 2;
2122 #if defined(DEBUG) 2122 #if defined(DEBUG)
2123 { Label ok; 2123 { Label ok;
2124 __ lw(TMP1, FieldAddress(T0, ICData::num_args_tested_offset())); 2124 __ lw(CMPRES1, FieldAddress(T0, ICData::num_args_tested_offset()));
2125 __ BranchEqual(TMP1, kNumArgsTested, &ok); 2125 __ BranchEqual(CMPRES1, kNumArgsTested, &ok);
2126 __ Stop("Incorrect ICData for equality"); 2126 __ Stop("Incorrect ICData for equality");
2127 __ Bind(&ok); 2127 __ Bind(&ok);
2128 } 2128 }
2129 #endif // DEBUG 2129 #endif // DEBUG
2130 // Check IC data, update if needed. 2130 // Check IC data, update if needed.
2131 // T0: IC data object (preserved). 2131 // T0: IC data object (preserved).
2132 __ lw(T6, FieldAddress(T0, ICData::ic_data_offset())); 2132 __ lw(T6, FieldAddress(T0, ICData::ic_data_offset()));
2133 // T6: ic_data_array with check entries: classes and target functions. 2133 // T6: ic_data_array with check entries: classes and target functions.
2134 __ AddImmediate(T6, Array::data_offset() - kHeapObjectTag); 2134 __ AddImmediate(T6, Array::data_offset() - kHeapObjectTag);
2135 // T6: points directly to the first ic data array element. 2135 // T6: points directly to the first ic data array element.
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
2312 __ CallRuntime(kBigintCompareRuntimeEntry); 2312 __ CallRuntime(kBigintCompareRuntimeEntry);
2313 __ TraceSimMsg("IdenticalWithNumberCheckStub return"); 2313 __ TraceSimMsg("IdenticalWithNumberCheckStub return");
2314 // Result in V0, 0 means equal. 2314 // Result in V0, 0 means equal.
2315 __ LeaveStubFrame(); 2315 __ LeaveStubFrame();
2316 __ b(&done); 2316 __ b(&done);
2317 __ delay_slot()->mov(CMPRES, V0); 2317 __ delay_slot()->mov(CMPRES, V0);
2318 2318
2319 __ Bind(&reference_compare); 2319 __ Bind(&reference_compare);
2320 __ subu(CMPRES, left, right); 2320 __ subu(CMPRES, left, right);
2321 __ Bind(&done); 2321 __ Bind(&done);
2322 // A branch or test after this comparison will check CMPRES == TMP1. 2322 // A branch or test after this comparison will check CMPRES1 == CMPRES2.
2323 __ mov(TMP1, ZR); 2323 __ mov(CMPRES2, ZR);
2324 } 2324 }
2325 2325
2326 2326
2327 // Called only from unoptimized code. All relevant registers have been saved. 2327 // Called only from unoptimized code. All relevant registers have been saved.
2328 // RA: return address. 2328 // RA: return address.
2329 // SP + 4: left operand. 2329 // SP + 4: left operand.
2330 // SP + 0: right operand. 2330 // SP + 0: right operand.
2331 // Returns: CMPRES is zero if equal, non-zero otherwise. 2331 // Returns: CMPRES is zero if equal, non-zero otherwise.
2332 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( 2332 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
2333 Assembler* assembler) { 2333 Assembler* assembler) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2380 __ lw(left, Address(SP, 1 * kWordSize)); 2380 __ lw(left, Address(SP, 1 * kWordSize));
2381 __ lw(temp2, Address(SP, 2 * kWordSize)); 2381 __ lw(temp2, Address(SP, 2 * kWordSize));
2382 __ lw(temp1, Address(SP, 3 * kWordSize)); 2382 __ lw(temp1, Address(SP, 3 * kWordSize));
2383 __ Ret(); 2383 __ Ret();
2384 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); 2384 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
2385 } 2385 }
2386 2386
2387 } // namespace dart 2387 } // namespace dart
2388 2388
2389 #endif // defined TARGET_ARCH_MIPS 2389 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698