| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 2135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 // convert it to 0. | 2146 // convert it to 0. |
| 2147 Fmov(dbl_scratch, 255); | 2147 Fmov(dbl_scratch, 255); |
| 2148 Fmin(dbl_scratch, dbl_scratch, input); | 2148 Fmin(dbl_scratch, dbl_scratch, input); |
| 2149 | 2149 |
| 2150 // Convert double to unsigned integer. Values less than zero become zero. | 2150 // Convert double to unsigned integer. Values less than zero become zero. |
| 2151 // Values greater than 255 have already been clamped to 255. | 2151 // Values greater than 255 have already been clamped to 255. |
| 2152 Fcvtnu(output, dbl_scratch); | 2152 Fcvtnu(output, dbl_scratch); |
| 2153 } | 2153 } |
| 2154 | 2154 |
| 2155 | 2155 |
| 2156 void MacroAssembler::CopyFieldsLoopPairsHelper(Register dst, | |
| 2157 Register src, | |
| 2158 unsigned count, | |
| 2159 Register scratch1, | |
| 2160 Register scratch2, | |
| 2161 Register scratch3, | |
| 2162 Register scratch4, | |
| 2163 Register scratch5) { | |
| 2164 // Untag src and dst into scratch registers. | |
| 2165 // Copy src->dst in a tight loop. | |
| 2166 DCHECK(!AreAliased(dst, src, | |
| 2167 scratch1, scratch2, scratch3, scratch4, scratch5)); | |
| 2168 DCHECK(count >= 2); | |
| 2169 | |
| 2170 const Register& remaining = scratch3; | |
| 2171 Mov(remaining, count / 2); | |
| 2172 | |
| 2173 const Register& dst_untagged = scratch1; | |
| 2174 const Register& src_untagged = scratch2; | |
| 2175 Sub(dst_untagged, dst, kHeapObjectTag); | |
| 2176 Sub(src_untagged, src, kHeapObjectTag); | |
| 2177 | |
| 2178 // Copy fields in pairs. | |
| 2179 Label loop; | |
| 2180 Bind(&loop); | |
| 2181 Ldp(scratch4, scratch5, | |
| 2182 MemOperand(src_untagged, kXRegSize* 2, PostIndex)); | |
| 2183 Stp(scratch4, scratch5, | |
| 2184 MemOperand(dst_untagged, kXRegSize* 2, PostIndex)); | |
| 2185 Sub(remaining, remaining, 1); | |
| 2186 Cbnz(remaining, &loop); | |
| 2187 | |
| 2188 // Handle the leftovers. | |
| 2189 if (count & 1) { | |
| 2190 Ldr(scratch4, MemOperand(src_untagged)); | |
| 2191 Str(scratch4, MemOperand(dst_untagged)); | |
| 2192 } | |
| 2193 } | |
| 2194 | |
| 2195 | |
| 2196 void MacroAssembler::CopyFieldsUnrolledPairsHelper(Register dst, | |
| 2197 Register src, | |
| 2198 unsigned count, | |
| 2199 Register scratch1, | |
| 2200 Register scratch2, | |
| 2201 Register scratch3, | |
| 2202 Register scratch4) { | |
| 2203 // Untag src and dst into scratch registers. | |
| 2204 // Copy src->dst in an unrolled loop. | |
| 2205 DCHECK(!AreAliased(dst, src, scratch1, scratch2, scratch3, scratch4)); | |
| 2206 | |
| 2207 const Register& dst_untagged = scratch1; | |
| 2208 const Register& src_untagged = scratch2; | |
| 2209 sub(dst_untagged, dst, kHeapObjectTag); | |
| 2210 sub(src_untagged, src, kHeapObjectTag); | |
| 2211 | |
| 2212 // Copy fields in pairs. | |
| 2213 for (unsigned i = 0; i < count / 2; i++) { | |
| 2214 Ldp(scratch3, scratch4, MemOperand(src_untagged, kXRegSize * 2, PostIndex)); | |
| 2215 Stp(scratch3, scratch4, MemOperand(dst_untagged, kXRegSize * 2, PostIndex)); | |
| 2216 } | |
| 2217 | |
| 2218 // Handle the leftovers. | |
| 2219 if (count & 1) { | |
| 2220 Ldr(scratch3, MemOperand(src_untagged)); | |
| 2221 Str(scratch3, MemOperand(dst_untagged)); | |
| 2222 } | |
| 2223 } | |
| 2224 | |
| 2225 | |
| 2226 void MacroAssembler::CopyFieldsUnrolledHelper(Register dst, | |
| 2227 Register src, | |
| 2228 unsigned count, | |
| 2229 Register scratch1, | |
| 2230 Register scratch2, | |
| 2231 Register scratch3) { | |
| 2232 // Untag src and dst into scratch registers. | |
| 2233 // Copy src->dst in an unrolled loop. | |
| 2234 DCHECK(!AreAliased(dst, src, scratch1, scratch2, scratch3)); | |
| 2235 | |
| 2236 const Register& dst_untagged = scratch1; | |
| 2237 const Register& src_untagged = scratch2; | |
| 2238 Sub(dst_untagged, dst, kHeapObjectTag); | |
| 2239 Sub(src_untagged, src, kHeapObjectTag); | |
| 2240 | |
| 2241 // Copy fields one by one. | |
| 2242 for (unsigned i = 0; i < count; i++) { | |
| 2243 Ldr(scratch3, MemOperand(src_untagged, kXRegSize, PostIndex)); | |
| 2244 Str(scratch3, MemOperand(dst_untagged, kXRegSize, PostIndex)); | |
| 2245 } | |
| 2246 } | |
| 2247 | |
| 2248 | |
| 2249 void MacroAssembler::CopyFields(Register dst, Register src, CPURegList temps, | |
| 2250 unsigned count) { | |
| 2251 // One of two methods is used: | |
| 2252 // | |
| 2253 // For high 'count' values where many scratch registers are available: | |
| 2254 // Untag src and dst into scratch registers. | |
| 2255 // Copy src->dst in a tight loop. | |
| 2256 // | |
| 2257 // For low 'count' values or where few scratch registers are available: | |
| 2258 // Untag src and dst into scratch registers. | |
| 2259 // Copy src->dst in an unrolled loop. | |
| 2260 // | |
| 2261 // In both cases, fields are copied in pairs if possible, and left-overs are | |
| 2262 // handled separately. | |
| 2263 DCHECK(!AreAliased(dst, src)); | |
| 2264 DCHECK(!temps.IncludesAliasOf(dst)); | |
| 2265 DCHECK(!temps.IncludesAliasOf(src)); | |
| 2266 DCHECK(!temps.IncludesAliasOf(xzr)); | |
| 2267 | |
| 2268 if (emit_debug_code()) { | |
| 2269 Cmp(dst, src); | |
| 2270 Check(ne, kTheSourceAndDestinationAreTheSame); | |
| 2271 } | |
| 2272 | |
| 2273 // The value of 'count' at which a loop will be generated (if there are | |
| 2274 // enough scratch registers). | |
| 2275 static const unsigned kLoopThreshold = 8; | |
| 2276 | |
| 2277 UseScratchRegisterScope masm_temps(this); | |
| 2278 if ((temps.Count() >= 3) && (count >= kLoopThreshold)) { | |
| 2279 CopyFieldsLoopPairsHelper(dst, src, count, | |
| 2280 Register(temps.PopLowestIndex()), | |
| 2281 Register(temps.PopLowestIndex()), | |
| 2282 Register(temps.PopLowestIndex()), | |
| 2283 masm_temps.AcquireX(), | |
| 2284 masm_temps.AcquireX()); | |
| 2285 } else if (temps.Count() >= 2) { | |
| 2286 CopyFieldsUnrolledPairsHelper(dst, src, count, | |
| 2287 Register(temps.PopLowestIndex()), | |
| 2288 Register(temps.PopLowestIndex()), | |
| 2289 masm_temps.AcquireX(), | |
| 2290 masm_temps.AcquireX()); | |
| 2291 } else if (temps.Count() == 1) { | |
| 2292 CopyFieldsUnrolledHelper(dst, src, count, | |
| 2293 Register(temps.PopLowestIndex()), | |
| 2294 masm_temps.AcquireX(), | |
| 2295 masm_temps.AcquireX()); | |
| 2296 } else { | |
| 2297 UNREACHABLE(); | |
| 2298 } | |
| 2299 } | |
| 2300 | |
| 2301 | |
| 2302 void MacroAssembler::CopyBytes(Register dst, | 2156 void MacroAssembler::CopyBytes(Register dst, |
| 2303 Register src, | 2157 Register src, |
| 2304 Register length, | 2158 Register length, |
| 2305 Register scratch, | 2159 Register scratch, |
| 2306 CopyHint hint) { | 2160 CopyHint hint) { |
| 2307 UseScratchRegisterScope temps(this); | 2161 UseScratchRegisterScope temps(this); |
| 2308 Register tmp1 = temps.AcquireX(); | 2162 Register tmp1 = temps.AcquireX(); |
| 2309 Register tmp2 = temps.AcquireX(); | 2163 Register tmp2 = temps.AcquireX(); |
| 2310 DCHECK(!AreAliased(src, dst, length, scratch, tmp1, tmp2)); | 2164 DCHECK(!AreAliased(src, dst, length, scratch, tmp1, tmp2)); |
| 2311 DCHECK(!AreAliased(src, dst, csp)); | 2165 DCHECK(!AreAliased(src, dst, csp)); |
| (...skipping 2762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5074 } | 4928 } |
| 5075 | 4929 |
| 5076 | 4930 |
| 5077 #undef __ | 4931 #undef __ |
| 5078 | 4932 |
| 5079 | 4933 |
| 5080 } // namespace internal | 4934 } // namespace internal |
| 5081 } // namespace v8 | 4935 } // namespace v8 |
| 5082 | 4936 |
| 5083 #endif // V8_TARGET_ARCH_ARM64 | 4937 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |