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

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

Issue 2874763003: Add AddImmediate(reg, int) to ARM64 assembler (Closed)
Patch Set: Fix bug Created 3 years, 7 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
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/stub_code_arm.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 __ b(&fall_through, NE); \ 190 __ b(&fall_through, NE); \
191 __ CompareRegisters(R2, ZR); \ 191 __ CompareRegisters(R2, ZR); \
192 __ b(&fall_through, LT); \ 192 __ b(&fall_through, LT); \
193 __ SmiUntag(R2); \ 193 __ SmiUntag(R2); \
194 /* Check for maximum allowed length. */ \ 194 /* Check for maximum allowed length. */ \
195 /* R2: untagged array length. */ \ 195 /* R2: untagged array length. */ \
196 __ CompareImmediate(R2, max_len); \ 196 __ CompareImmediate(R2, max_len); \
197 __ b(&fall_through, GT); \ 197 __ b(&fall_through, GT); \
198 __ LslImmediate(R2, R2, scale_shift); \ 198 __ LslImmediate(R2, R2, scale_shift); \
199 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ 199 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \
200 __ AddImmediate(R2, R2, fixed_size); \ 200 __ AddImmediate(R2, fixed_size); \
201 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); \ 201 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); \
202 Heap::Space space = Heap::kNew; \ 202 Heap::Space space = Heap::kNew; \
203 __ ldr(R3, Address(THR, Thread::heap_offset())); \ 203 __ ldr(R3, Address(THR, Thread::heap_offset())); \
204 __ ldr(R0, Address(R3, Heap::TopOffset(space))); \ 204 __ ldr(R0, Address(R3, Heap::TopOffset(space))); \
205 \ 205 \
206 /* R2: allocation size. */ \ 206 /* R2: allocation size. */ \
207 __ adds(R1, R0, Operand(R2)); \ 207 __ adds(R1, R0, Operand(R2)); \
208 __ b(&fall_through, CS); /* Fail on unsigned overflow. */ \ 208 __ b(&fall_through, CS); /* Fail on unsigned overflow. */ \
209 \ 209 \
210 /* Check if the allocation fits into the remaining space. */ \ 210 /* Check if the allocation fits into the remaining space. */ \
211 /* R0: potential new object start. */ \ 211 /* R0: potential new object start. */ \
212 /* R1: potential next object start. */ \ 212 /* R1: potential next object start. */ \
213 /* R2: allocation size. */ \ 213 /* R2: allocation size. */ \
214 /* R3: heap. */ \ 214 /* R3: heap. */ \
215 __ ldr(R6, Address(R3, Heap::EndOffset(space))); \ 215 __ ldr(R6, Address(R3, Heap::EndOffset(space))); \
216 __ cmp(R1, Operand(R6)); \ 216 __ cmp(R1, Operand(R6)); \
217 __ b(&fall_through, CS); \ 217 __ b(&fall_through, CS); \
218 \ 218 \
219 /* Successfully allocated the object(s), now update top to point to */ \ 219 /* Successfully allocated the object(s), now update top to point to */ \
220 /* next object start and initialize the object. */ \ 220 /* next object start and initialize the object. */ \
221 __ str(R1, Address(R3, Heap::TopOffset(space))); \ 221 __ str(R1, Address(R3, Heap::TopOffset(space))); \
222 __ AddImmediate(R0, R0, kHeapObjectTag); \ 222 __ AddImmediate(R0, kHeapObjectTag); \
223 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space)); \ 223 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space)); \
224 /* Initialize the tags. */ \ 224 /* Initialize the tags. */ \
225 /* R0: new object start as a tagged pointer. */ \ 225 /* R0: new object start as a tagged pointer. */ \
226 /* R1: new object end address. */ \ 226 /* R1: new object end address. */ \
227 /* R2: allocation size. */ \ 227 /* R2: allocation size. */ \
228 { \ 228 { \
229 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); \ 229 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); \
230 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \ 230 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \
231 __ csel(R2, ZR, R2, HI); \ 231 __ csel(R2, ZR, R2, HI); \
232 \ 232 \
(...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1849 // if (start < 0) return false; 1849 // if (start < 0) return false;
1850 __ cmp(R1, Operand(0)); 1850 __ cmp(R1, Operand(0));
1851 __ b(return_false, LT); 1851 __ b(return_false, LT);
1852 1852
1853 // if (start + other.length > this.length) return false; 1853 // if (start + other.length > this.length) return false;
1854 __ add(R3, R1, Operand(R9)); 1854 __ add(R3, R1, Operand(R9));
1855 __ cmp(R3, Operand(R8)); 1855 __ cmp(R3, Operand(R8));
1856 __ b(return_false, GT); 1856 __ b(return_false, GT);
1857 1857
1858 if (receiver_cid == kOneByteStringCid) { 1858 if (receiver_cid == kOneByteStringCid) {
1859 __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag); 1859 __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
1860 __ add(R0, R0, Operand(R1)); 1860 __ add(R0, R0, Operand(R1));
1861 } else { 1861 } else {
1862 ASSERT(receiver_cid == kTwoByteStringCid); 1862 ASSERT(receiver_cid == kTwoByteStringCid);
1863 __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag); 1863 __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
1864 __ add(R0, R0, Operand(R1)); 1864 __ add(R0, R0, Operand(R1));
1865 __ add(R0, R0, Operand(R1)); 1865 __ add(R0, R0, Operand(R1));
1866 } 1866 }
1867 if (other_cid == kOneByteStringCid) { 1867 if (other_cid == kOneByteStringCid) {
1868 __ AddImmediate(R2, R2, OneByteString::data_offset() - kHeapObjectTag); 1868 __ AddImmediate(R2, OneByteString::data_offset() - kHeapObjectTag);
1869 } else { 1869 } else {
1870 ASSERT(other_cid == kTwoByteStringCid); 1870 ASSERT(other_cid == kTwoByteStringCid);
1871 __ AddImmediate(R2, R2, TwoByteString::data_offset() - kHeapObjectTag); 1871 __ AddImmediate(R2, TwoByteString::data_offset() - kHeapObjectTag);
1872 } 1872 }
1873 1873
1874 // i = 0 1874 // i = 0
1875 __ LoadImmediate(R3, 0); 1875 __ LoadImmediate(R3, 0);
1876 1876
1877 // do 1877 // do
1878 Label loop; 1878 Label loop;
1879 __ Bind(&loop); 1879 __ Bind(&loop);
1880 1880
1881 // this.codeUnitAt(i + start) 1881 // this.codeUnitAt(i + start)
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 __ tsti(R1, Immediate(kSmiTagMask)); 1948 __ tsti(R1, Immediate(kSmiTagMask));
1949 __ b(&fall_through, NE); // Index is not a Smi. 1949 __ b(&fall_through, NE); // Index is not a Smi.
1950 // Range check. 1950 // Range check.
1951 __ ldr(R2, FieldAddress(R0, String::length_offset())); 1951 __ ldr(R2, FieldAddress(R0, String::length_offset()));
1952 __ cmp(R1, Operand(R2)); 1952 __ cmp(R1, Operand(R2));
1953 __ b(&fall_through, CS); // Runtime throws exception. 1953 __ b(&fall_through, CS); // Runtime throws exception.
1954 1954
1955 __ CompareClassId(R0, kOneByteStringCid); 1955 __ CompareClassId(R0, kOneByteStringCid);
1956 __ b(&try_two_byte_string, NE); 1956 __ b(&try_two_byte_string, NE);
1957 __ SmiUntag(R1); 1957 __ SmiUntag(R1);
1958 __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag); 1958 __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
1959 __ ldr(R1, Address(R0, R1), kUnsignedByte); 1959 __ ldr(R1, Address(R0, R1), kUnsignedByte);
1960 __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols); 1960 __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
1961 __ b(&fall_through, GE); 1961 __ b(&fall_through, GE);
1962 __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset())); 1962 __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
1963 __ AddImmediate(R0, R0, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1963 __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1964 __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled)); 1964 __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
1965 __ ret(); 1965 __ ret();
1966 1966
1967 __ Bind(&try_two_byte_string); 1967 __ Bind(&try_two_byte_string);
1968 __ CompareClassId(R0, kTwoByteStringCid); 1968 __ CompareClassId(R0, kTwoByteStringCid);
1969 __ b(&fall_through, NE); 1969 __ b(&fall_through, NE);
1970 ASSERT(kSmiTagShift == 1); 1970 ASSERT(kSmiTagShift == 1);
1971 __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag); 1971 __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
1972 __ ldr(R1, Address(R0, R1), kUnsignedHalfword); 1972 __ ldr(R1, Address(R0, R1), kUnsignedHalfword);
1973 __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols); 1973 __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
1974 __ b(&fall_through, GE); 1974 __ b(&fall_through, GE);
1975 __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset())); 1975 __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
1976 __ AddImmediate(R0, R0, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1976 __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1977 __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled)); 1977 __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
1978 __ ret(); 1978 __ ret();
1979 1979
1980 __ Bind(&fall_through); 1980 __ Bind(&fall_through);
1981 } 1981 }
1982 1982
1983 1983
1984 void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) { 1984 void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) {
1985 __ ldr(R0, Address(SP, 0 * kWordSize)); 1985 __ ldr(R0, Address(SP, 0 * kWordSize));
1986 __ ldr(R0, FieldAddress(R0, String::length_offset())); 1986 __ ldr(R0, FieldAddress(R0, String::length_offset()));
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 static void TryAllocateOnebyteString(Assembler* assembler, 2059 static void TryAllocateOnebyteString(Assembler* assembler,
2060 Label* ok, 2060 Label* ok,
2061 Label* failure) { 2061 Label* failure) {
2062 const Register length_reg = R2; 2062 const Register length_reg = R2;
2063 Label fail; 2063 Label fail;
2064 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, R0, failure)); 2064 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, R0, failure));
2065 __ mov(R6, length_reg); // Save the length register. 2065 __ mov(R6, length_reg); // Save the length register.
2066 // TODO(koda): Protect against negative length and overflow here. 2066 // TODO(koda): Protect against negative length and overflow here.
2067 __ SmiUntag(length_reg); 2067 __ SmiUntag(length_reg);
2068 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; 2068 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
2069 __ AddImmediate(length_reg, length_reg, fixed_size); 2069 __ AddImmediate(length_reg, fixed_size);
2070 __ andi(length_reg, length_reg, Immediate(~(kObjectAlignment - 1))); 2070 __ andi(length_reg, length_reg, Immediate(~(kObjectAlignment - 1)));
2071 2071
2072 const intptr_t cid = kOneByteStringCid; 2072 const intptr_t cid = kOneByteStringCid;
2073 Heap::Space space = Heap::kNew; 2073 Heap::Space space = Heap::kNew;
2074 __ ldr(R3, Address(THR, Thread::heap_offset())); 2074 __ ldr(R3, Address(THR, Thread::heap_offset()));
2075 __ ldr(R0, Address(R3, Heap::TopOffset(space))); 2075 __ ldr(R0, Address(R3, Heap::TopOffset(space)));
2076 2076
2077 // length_reg: allocation size. 2077 // length_reg: allocation size.
2078 __ adds(R1, R0, Operand(length_reg)); 2078 __ adds(R1, R0, Operand(length_reg));
2079 __ b(&fail, CS); // Fail on unsigned overflow. 2079 __ b(&fail, CS); // Fail on unsigned overflow.
2080 2080
2081 // Check if the allocation fits into the remaining space. 2081 // Check if the allocation fits into the remaining space.
2082 // R0: potential new object start. 2082 // R0: potential new object start.
2083 // R1: potential next object start. 2083 // R1: potential next object start.
2084 // R2: allocation size. 2084 // R2: allocation size.
2085 // R3: heap. 2085 // R3: heap.
2086 __ ldr(R7, Address(R3, Heap::EndOffset(space))); 2086 __ ldr(R7, Address(R3, Heap::EndOffset(space)));
2087 __ cmp(R1, Operand(R7)); 2087 __ cmp(R1, Operand(R7));
2088 __ b(&fail, CS); 2088 __ b(&fail, CS);
2089 2089
2090 // Successfully allocated the object(s), now update top to point to 2090 // Successfully allocated the object(s), now update top to point to
2091 // next object start and initialize the object. 2091 // next object start and initialize the object.
2092 __ str(R1, Address(R3, Heap::TopOffset(space))); 2092 __ str(R1, Address(R3, Heap::TopOffset(space)));
2093 __ AddImmediate(R0, R0, kHeapObjectTag); 2093 __ AddImmediate(R0, kHeapObjectTag);
2094 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space)); 2094 NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space));
2095 2095
2096 // Initialize the tags. 2096 // Initialize the tags.
2097 // R0: new object start as a tagged pointer. 2097 // R0: new object start as a tagged pointer.
2098 // R1: new object end address. 2098 // R1: new object end address.
2099 // R2: allocation size. 2099 // R2: allocation size.
2100 { 2100 {
2101 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 2101 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
2102 2102
2103 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); 2103 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 __ sub(R2, R2, Operand(TMP)); 2143 __ sub(R2, R2, Operand(TMP));
2144 TryAllocateOnebyteString(assembler, &ok, &fall_through); 2144 TryAllocateOnebyteString(assembler, &ok, &fall_through);
2145 __ Bind(&ok); 2145 __ Bind(&ok);
2146 // R0: new string as tagged pointer. 2146 // R0: new string as tagged pointer.
2147 // Copy string. 2147 // Copy string.
2148 __ ldr(R3, Address(SP, kStringOffset)); 2148 __ ldr(R3, Address(SP, kStringOffset));
2149 __ ldr(R1, Address(SP, kStartIndexOffset)); 2149 __ ldr(R1, Address(SP, kStartIndexOffset));
2150 __ SmiUntag(R1); 2150 __ SmiUntag(R1);
2151 __ add(R3, R3, Operand(R1)); 2151 __ add(R3, R3, Operand(R1));
2152 // Calculate start address and untag (- 1). 2152 // Calculate start address and untag (- 1).
2153 __ AddImmediate(R3, R3, OneByteString::data_offset() - 1); 2153 __ AddImmediate(R3, OneByteString::data_offset() - 1);
2154 2154
2155 // R3: Start address to copy from (untagged). 2155 // R3: Start address to copy from (untagged).
2156 // R1: Untagged start index. 2156 // R1: Untagged start index.
2157 __ ldr(R2, Address(SP, kEndIndexOffset)); 2157 __ ldr(R2, Address(SP, kEndIndexOffset));
2158 __ SmiUntag(R2); 2158 __ SmiUntag(R2);
2159 __ sub(R2, R2, Operand(R1)); 2159 __ sub(R2, R2, Operand(R1));
2160 2160
2161 // R3: Start address to copy from (untagged). 2161 // R3: Start address to copy from (untagged).
2162 // R2: Untagged number of bytes to copy. 2162 // R2: Untagged number of bytes to copy.
2163 // R0: Tagged result string. 2163 // R0: Tagged result string.
2164 // R6: Pointer into R3. 2164 // R6: Pointer into R3.
2165 // R7: Pointer into R0. 2165 // R7: Pointer into R0.
2166 // R1: Scratch register. 2166 // R1: Scratch register.
2167 Label loop, done; 2167 Label loop, done;
2168 __ cmp(R2, Operand(0)); 2168 __ cmp(R2, Operand(0));
2169 __ b(&done, LE); 2169 __ b(&done, LE);
2170 __ mov(R6, R3); 2170 __ mov(R6, R3);
2171 __ mov(R7, R0); 2171 __ mov(R7, R0);
2172 __ Bind(&loop); 2172 __ Bind(&loop);
2173 __ ldr(R1, Address(R6), kUnsignedByte); 2173 __ ldr(R1, Address(R6), kUnsignedByte);
2174 __ AddImmediate(R6, R6, 1); 2174 __ AddImmediate(R6, 1);
2175 __ sub(R2, R2, Operand(1)); 2175 __ sub(R2, R2, Operand(1));
2176 __ cmp(R2, Operand(0)); 2176 __ cmp(R2, Operand(0));
2177 __ str(R1, FieldAddress(R7, OneByteString::data_offset()), kUnsignedByte); 2177 __ str(R1, FieldAddress(R7, OneByteString::data_offset()), kUnsignedByte);
2178 __ AddImmediate(R7, R7, 1); 2178 __ AddImmediate(R7, 1);
2179 __ b(&loop, GT); 2179 __ b(&loop, GT);
2180 2180
2181 __ Bind(&done); 2181 __ Bind(&done);
2182 __ ret(); 2182 __ ret();
2183 __ Bind(&fall_through); 2183 __ Bind(&fall_through);
2184 } 2184 }
2185 2185
2186 2186
2187 void Intrinsifier::OneByteStringSetAt(Assembler* assembler) { 2187 void Intrinsifier::OneByteStringSetAt(Assembler* assembler) {
2188 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value. 2188 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 __ cmp(R2, Operand(R3)); 2231 __ cmp(R2, Operand(R3));
2232 __ b(&is_false, NE); 2232 __ b(&is_false, NE);
2233 2233
2234 // Check contents, no fall-through possible. 2234 // Check contents, no fall-through possible.
2235 // TODO(zra): try out other sequences. 2235 // TODO(zra): try out other sequences.
2236 ASSERT((string_cid == kOneByteStringCid) || 2236 ASSERT((string_cid == kOneByteStringCid) ||
2237 (string_cid == kTwoByteStringCid)); 2237 (string_cid == kTwoByteStringCid));
2238 const intptr_t offset = (string_cid == kOneByteStringCid) 2238 const intptr_t offset = (string_cid == kOneByteStringCid)
2239 ? OneByteString::data_offset() 2239 ? OneByteString::data_offset()
2240 : TwoByteString::data_offset(); 2240 : TwoByteString::data_offset();
2241 __ AddImmediate(R0, R0, offset - kHeapObjectTag); 2241 __ AddImmediate(R0, offset - kHeapObjectTag);
2242 __ AddImmediate(R1, R1, offset - kHeapObjectTag); 2242 __ AddImmediate(R1, offset - kHeapObjectTag);
2243 __ SmiUntag(R2); 2243 __ SmiUntag(R2);
2244 __ Bind(&loop); 2244 __ Bind(&loop);
2245 __ AddImmediate(R2, R2, -1); 2245 __ AddImmediate(R2, -1);
2246 __ CompareRegisters(R2, ZR); 2246 __ CompareRegisters(R2, ZR);
2247 __ b(&is_true, LT); 2247 __ b(&is_true, LT);
2248 if (string_cid == kOneByteStringCid) { 2248 if (string_cid == kOneByteStringCid) {
2249 __ ldr(R3, Address(R0), kUnsignedByte); 2249 __ ldr(R3, Address(R0), kUnsignedByte);
2250 __ ldr(R4, Address(R1), kUnsignedByte); 2250 __ ldr(R4, Address(R1), kUnsignedByte);
2251 __ AddImmediate(R0, R0, 1); 2251 __ AddImmediate(R0, 1);
2252 __ AddImmediate(R1, R1, 1); 2252 __ AddImmediate(R1, 1);
2253 } else if (string_cid == kTwoByteStringCid) { 2253 } else if (string_cid == kTwoByteStringCid) {
2254 __ ldr(R3, Address(R0), kUnsignedHalfword); 2254 __ ldr(R3, Address(R0), kUnsignedHalfword);
2255 __ ldr(R4, Address(R1), kUnsignedHalfword); 2255 __ ldr(R4, Address(R1), kUnsignedHalfword);
2256 __ AddImmediate(R0, R0, 2); 2256 __ AddImmediate(R0, 2);
2257 __ AddImmediate(R1, R1, 2); 2257 __ AddImmediate(R1, 2);
2258 } else { 2258 } else {
2259 UNIMPLEMENTED(); 2259 UNIMPLEMENTED();
2260 } 2260 }
2261 __ cmp(R3, Operand(R4)); 2261 __ cmp(R3, Operand(R4));
2262 __ b(&is_false, NE); 2262 __ b(&is_false, NE);
2263 __ b(&loop); 2263 __ b(&loop);
2264 2264
2265 __ Bind(&is_true); 2265 __ Bind(&is_true);
2266 __ LoadObject(R0, Bool::True()); 2266 __ LoadObject(R0, Bool::True());
2267 __ ret(); 2267 __ ret();
(...skipping 27 matching lines...) Expand all
2295 // Incoming registers: 2295 // Incoming registers:
2296 // R0: Function. (Will be reloaded with the specialized matcher function.) 2296 // R0: Function. (Will be reloaded with the specialized matcher function.)
2297 // R4: Arguments descriptor. (Will be preserved.) 2297 // R4: Arguments descriptor. (Will be preserved.)
2298 // R5: Unknown. (Must be GC safe on tail call.) 2298 // R5: Unknown. (Must be GC safe on tail call.)
2299 2299
2300 // Load the specialized function pointer into R0. Leverage the fact the 2300 // Load the specialized function pointer into R0. Leverage the fact the
2301 // string CIDs as well as stored function pointers are in sequence. 2301 // string CIDs as well as stored function pointers are in sequence.
2302 __ ldr(R2, Address(SP, kRegExpParamOffset)); 2302 __ ldr(R2, Address(SP, kRegExpParamOffset));
2303 __ ldr(R1, Address(SP, kStringParamOffset)); 2303 __ ldr(R1, Address(SP, kStringParamOffset));
2304 __ LoadClassId(R1, R1); 2304 __ LoadClassId(R1, R1);
2305 __ AddImmediate(R1, R1, -kOneByteStringCid); 2305 __ AddImmediate(R1, -kOneByteStringCid);
2306 __ add(R1, R2, Operand(R1, LSL, kWordSizeLog2)); 2306 __ add(R1, R2, Operand(R1, LSL, kWordSizeLog2));
2307 __ ldr(R0, 2307 __ ldr(R0,
2308 FieldAddress(R1, RegExp::function_offset(kOneByteStringCid, sticky))); 2308 FieldAddress(R1, RegExp::function_offset(kOneByteStringCid, sticky)));
2309 2309
2310 // Registers are now set up for the lazy compile stub. It expects the function 2310 // Registers are now set up for the lazy compile stub. It expects the function
2311 // in R0, the argument descriptor in R4, and IC-Data in R5. 2311 // in R0, the argument descriptor in R4, and IC-Data in R5.
2312 __ eor(R5, R5, Operand(R5)); 2312 __ eor(R5, R5, Operand(R5));
2313 2313
2314 // Tail-call the function. 2314 // Tail-call the function.
2315 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset())); 2315 __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 2377
2378 void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) { 2378 void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler) {
2379 __ ldr(R0, Address(THR, Thread::async_stack_trace_offset())); 2379 __ ldr(R0, Address(THR, Thread::async_stack_trace_offset()));
2380 __ LoadObject(R0, Object::null_object()); 2380 __ LoadObject(R0, Object::null_object());
2381 __ ret(); 2381 __ ret();
2382 } 2382 }
2383 2383
2384 } // namespace dart 2384 } // namespace dart
2385 2385
2386 #endif // defined TARGET_ARCH_ARM64 2386 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/stub_code_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698