OLD | NEW |
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 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 __ lw(RA, Address(SP, 0 * kWordSize)); | 1856 __ lw(RA, Address(SP, 0 * kWordSize)); |
1857 __ addiu(SP, SP, Immediate(1 * kWordSize)); | 1857 __ addiu(SP, SP, Immediate(1 * kWordSize)); |
1858 __ LeaveStubFrame(); | 1858 __ LeaveStubFrame(); |
1859 __ b(&done_stepping); | 1859 __ b(&done_stepping); |
1860 } | 1860 } |
1861 | 1861 |
1862 | 1862 |
1863 // Used to check class and type arguments. Arguments passed in registers: | 1863 // Used to check class and type arguments. Arguments passed in registers: |
1864 // RA: return address. | 1864 // RA: return address. |
1865 // A0: instance (must be preserved). | 1865 // A0: instance (must be preserved). |
1866 // A1: instantiator type arguments or NULL. | 1866 // A1: instantiator type arguments (only if n == 4, can be raw_null). |
1867 // A2: cache array. | 1867 // A2: function type arguments (only if n == 4, can be raw_null). |
| 1868 // A3: SubtypeTestCache. |
1868 // Result in V0: null -> not found, otherwise result (true or false). | 1869 // Result in V0: null -> not found, otherwise result (true or false). |
1869 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1870 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
1870 __ Comment("SubtypeNTestCacheStub"); | 1871 __ Comment("SubtypeNTestCacheStub"); |
1871 ASSERT((1 <= n) && (n <= 3)); | 1872 ASSERT((n == 1) || (n == 2) || (n == 4)); |
1872 if (n > 1) { | 1873 if (n > 1) { |
1873 // Get instance type arguments. | |
1874 __ LoadClass(T0, A0); | 1874 __ LoadClass(T0, A0); |
1875 // Compute instance type arguments into T1. | 1875 // Compute instance type arguments into T1. |
1876 Label has_no_type_arguments; | 1876 Label has_no_type_arguments; |
1877 __ LoadObject(T1, Object::null_object()); | 1877 __ LoadObject(T1, Object::null_object()); |
1878 __ lw(T2, FieldAddress( | 1878 __ lw(T2, FieldAddress( |
1879 T0, Class::type_arguments_field_offset_in_words_offset())); | 1879 T0, Class::type_arguments_field_offset_in_words_offset())); |
1880 __ BranchEqual(T2, Immediate(Class::kNoTypeArguments), | 1880 __ BranchEqual(T2, Immediate(Class::kNoTypeArguments), |
1881 &has_no_type_arguments); | 1881 &has_no_type_arguments); |
1882 __ sll(T2, T2, 2); | 1882 __ sll(T2, T2, 2); |
1883 __ addu(T2, A0, T2); // T2 <- A0 + T2 * 4 | 1883 __ addu(T2, A0, T2); // T2 <- A0 + T2 * 4 |
1884 __ lw(T1, FieldAddress(T2, 0)); | 1884 __ lw(T1, FieldAddress(T2, 0)); |
1885 __ Bind(&has_no_type_arguments); | 1885 __ Bind(&has_no_type_arguments); |
1886 } | 1886 } |
1887 __ LoadClassId(T0, A0); | 1887 __ LoadClassId(T0, A0); |
1888 // A0: instance. | 1888 // A0: instance. |
1889 // A1: instantiator type arguments or NULL. | 1889 // A1: instantiator type arguments (only if n == 4, can be raw_null). |
1890 // A2: SubtypeTestCache. | 1890 // A2: function type arguments (only if n == 4, can be raw_null). |
| 1891 // A3: SubtypeTestCache. |
1891 // T0: instance class id. | 1892 // T0: instance class id. |
1892 // T1: instance type arguments (null if none), used only if n > 1. | 1893 // T1: instance type arguments (null if none), used only if n > 1. |
1893 __ lw(T2, FieldAddress(A2, SubtypeTestCache::cache_offset())); | 1894 __ lw(T2, FieldAddress(A3, SubtypeTestCache::cache_offset())); |
1894 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | 1895 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
1895 | 1896 |
1896 __ LoadObject(T7, Object::null_object()); | 1897 __ LoadObject(T7, Object::null_object()); |
1897 | |
1898 Label loop, found, not_found, next_iteration; | 1898 Label loop, found, not_found, next_iteration; |
1899 // T0: instance class id. | 1899 // T0: instance class id. |
1900 // T1: instance type arguments (still null if closure). | 1900 // T1: instance type arguments (still null if closure). |
1901 // T2: Entry start. | 1901 // T2: Entry start. |
1902 // T7: null. | 1902 // T7: null. |
1903 __ SmiTag(T0); | 1903 __ SmiTag(T0); |
1904 __ BranchNotEqual(T0, Immediate(Smi::RawValue(kClosureCid)), &loop); | 1904 __ BranchNotEqual(T0, Immediate(Smi::RawValue(kClosureCid)), &loop); |
1905 __ lw(T1, FieldAddress(A0, Closure::instantiator_offset())); | 1905 __ lw(T1, FieldAddress(A0, Closure::instantiator_offset())); |
1906 __ lw(T0, FieldAddress(A0, Closure::function_offset())); | 1906 __ lw(T0, FieldAddress(A0, Closure::function_offset())); |
1907 // T0: instance class id as Smi or function. | 1907 // T0: instance class id as Smi or function. |
1908 __ Bind(&loop); | 1908 __ Bind(&loop); |
1909 __ lw(T3, | 1909 __ lw(T3, |
1910 Address(T2, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction)); | 1910 Address(T2, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction)); |
1911 __ beq(T3, T7, ¬_found); | 1911 __ beq(T3, T7, ¬_found); |
1912 | |
1913 if (n == 1) { | 1912 if (n == 1) { |
1914 __ beq(T3, T0, &found); | 1913 __ beq(T3, T0, &found); |
1915 } else { | 1914 } else { |
1916 __ bne(T3, T0, &next_iteration); | 1915 __ bne(T3, T0, &next_iteration); |
1917 __ lw(T3, | 1916 __ lw(T3, |
1918 Address(T2, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); | 1917 Address(T2, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); |
1919 if (n == 2) { | 1918 if (n == 2) { |
1920 __ beq(T3, T1, &found); | 1919 __ beq(T3, T1, &found); |
1921 } else { | 1920 } else { |
1922 __ bne(T3, T1, &next_iteration); | 1921 __ bne(T3, T1, &next_iteration); |
1923 __ lw(T3, Address(T2, kWordSize * | 1922 __ lw(T3, Address(T2, kWordSize * |
1924 SubtypeTestCache::kInstantiatorTypeArguments)); | 1923 SubtypeTestCache::kInstantiatorTypeArguments)); |
1925 __ beq(T3, A1, &found); | 1924 __ bne(T3, A1, &next_iteration); |
| 1925 __ lw(T3, |
| 1926 Address(T2, kWordSize * SubtypeTestCache::kFunctionTypeArguments)); |
| 1927 __ beq(T3, A2, &found); |
1926 } | 1928 } |
1927 } | 1929 } |
1928 __ Bind(&next_iteration); | 1930 __ Bind(&next_iteration); |
1929 __ b(&loop); | 1931 __ b(&loop); |
1930 __ delay_slot()->addiu( | 1932 __ delay_slot()->addiu( |
1931 T2, T2, Immediate(kWordSize * SubtypeTestCache::kTestEntryLength)); | 1933 T2, T2, Immediate(kWordSize * SubtypeTestCache::kTestEntryLength)); |
1932 // Fall through to not found. | 1934 // Fall through to not found. |
1933 __ Bind(¬_found); | 1935 __ Bind(¬_found); |
1934 __ Ret(); | 1936 __ Ret(); |
1935 __ delay_slot()->mov(V0, T7); | 1937 __ delay_slot()->mov(V0, T7); |
1936 | 1938 |
1937 __ Bind(&found); | 1939 __ Bind(&found); |
1938 __ Ret(); | 1940 __ Ret(); |
1939 __ delay_slot()->lw(V0, | 1941 __ delay_slot()->lw(V0, |
1940 Address(T2, kWordSize * SubtypeTestCache::kTestResult)); | 1942 Address(T2, kWordSize * SubtypeTestCache::kTestResult)); |
1941 } | 1943 } |
1942 | 1944 |
1943 | 1945 |
1944 // Used to check class and type arguments. Arguments passed in registers: | 1946 // Used to check class and type arguments. Arguments passed in registers: |
1945 // RA: return address. | 1947 // RA: return address. |
1946 // A0: instance (must be preserved). | 1948 // A0: instance (must be preserved). |
1947 // A1: instantiator type arguments or NULL. | 1949 // A1: unused. |
1948 // A2: cache array. | 1950 // A2: unused. |
| 1951 // A3: SubtypeTestCache. |
1949 // Result in V0: null -> not found, otherwise result (true or false). | 1952 // Result in V0: null -> not found, otherwise result (true or false). |
1950 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { | 1953 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { |
1951 GenerateSubtypeNTestCacheStub(assembler, 1); | 1954 GenerateSubtypeNTestCacheStub(assembler, 1); |
1952 } | 1955 } |
1953 | 1956 |
1954 | 1957 |
1955 // Used to check class and type arguments. Arguments passed in registers: | 1958 // Used to check class and type arguments. Arguments passed in registers: |
1956 // RA: return address. | 1959 // RA: return address. |
1957 // A0: instance (must be preserved). | 1960 // A0: instance (must be preserved). |
1958 // A1: instantiator type arguments or NULL. | 1961 // A1: unused. |
1959 // A2: cache array. | 1962 // A2: unused. |
| 1963 // A3: SubtypeTestCache. |
1960 // Result in V0: null -> not found, otherwise result (true or false). | 1964 // Result in V0: null -> not found, otherwise result (true or false). |
1961 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { | 1965 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { |
1962 GenerateSubtypeNTestCacheStub(assembler, 2); | 1966 GenerateSubtypeNTestCacheStub(assembler, 2); |
1963 } | 1967 } |
1964 | 1968 |
1965 | 1969 |
1966 // Used to check class and type arguments. Arguments passed in registers: | 1970 // Used to check class and type arguments. Arguments passed in registers: |
1967 // RA: return address. | 1971 // RA: return address. |
1968 // A0: instance (must be preserved). | 1972 // A0: instance (must be preserved). |
1969 // A1: instantiator type arguments or NULL. | 1973 // A1: instantiator type arguments (can be raw_null). |
1970 // A2: cache array. | 1974 // A2: function type arguments (can be raw_null). |
| 1975 // A3: SubtypeTestCache. |
1971 // Result in V0: null -> not found, otherwise result (true or false). | 1976 // Result in V0: null -> not found, otherwise result (true or false). |
1972 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { | 1977 void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) { |
1973 GenerateSubtypeNTestCacheStub(assembler, 3); | 1978 GenerateSubtypeNTestCacheStub(assembler, 4); |
1974 } | 1979 } |
1975 | 1980 |
1976 | 1981 |
1977 // Return the current stack pointer address, used to stack alignment | 1982 // Return the current stack pointer address, used to stack alignment |
1978 // checks. | 1983 // checks. |
1979 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { | 1984 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { |
1980 __ Ret(); | 1985 __ Ret(); |
1981 __ delay_slot()->mov(V0, SP); | 1986 __ delay_slot()->mov(V0, SP); |
1982 } | 1987 } |
1983 | 1988 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2425 } | 2430 } |
2426 | 2431 |
2427 | 2432 |
2428 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2433 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
2429 __ break_(0); | 2434 __ break_(0); |
2430 } | 2435 } |
2431 | 2436 |
2432 } // namespace dart | 2437 } // namespace dart |
2433 | 2438 |
2434 #endif // defined TARGET_ARCH_MIPS | 2439 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |