2172 // have to fall back to the JNI stub |
2172 // have to fall back to the JNI stub |
2173 __ stp(dst, dst_pos, Address(sp, 0*BytesPerWord)); |
2173 __ stp(dst, dst_pos, Address(sp, 0*BytesPerWord)); |
2174 __ stp(length, src_pos, Address(sp, 2*BytesPerWord)); |
2174 __ stp(length, src_pos, Address(sp, 2*BytesPerWord)); |
2175 __ str(src, Address(sp, 4*BytesPerWord)); |
2175 __ str(src, Address(sp, 4*BytesPerWord)); |
2176 |
2176 |
2177 address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); |
|
2178 address copyfunc_addr = StubRoutines::generic_arraycopy(); |
2177 address copyfunc_addr = StubRoutines::generic_arraycopy(); |
|
2178 assert(copyfunc_addr != NULL, "generic arraycopy stub required"); |
2179 |
2179 |
2180 // The arguments are in java calling convention so we shift them |
2180 // The arguments are in java calling convention so we shift them |
2181 // to C convention |
2181 // to C convention |
2182 assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); |
2182 assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4); |
2183 __ mov(c_rarg0, j_rarg0); |
2183 __ mov(c_rarg0, j_rarg0); |
2186 assert_different_registers(c_rarg2, j_rarg3, j_rarg4); |
2186 assert_different_registers(c_rarg2, j_rarg3, j_rarg4); |
2187 __ mov(c_rarg2, j_rarg2); |
2187 __ mov(c_rarg2, j_rarg2); |
2188 assert_different_registers(c_rarg3, j_rarg4); |
2188 assert_different_registers(c_rarg3, j_rarg4); |
2189 __ mov(c_rarg3, j_rarg3); |
2189 __ mov(c_rarg3, j_rarg3); |
2190 __ mov(c_rarg4, j_rarg4); |
2190 __ mov(c_rarg4, j_rarg4); |
2191 if (copyfunc_addr == NULL) { // Use C version if stub was not generated |
|
2192 __ mov(rscratch1, RuntimeAddress(C_entry)); |
|
2193 __ blrt(rscratch1, 5, 0, 1); |
|
2194 } else { |
|
2195 #ifndef PRODUCT |
2191 #ifndef PRODUCT |
2196 if (PrintC1Statistics) { |
2192 if (PrintC1Statistics) { |
2197 __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); |
2193 __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); |
2198 } |
2194 } |
2199 #endif |
2195 #endif |
2200 __ far_call(RuntimeAddress(copyfunc_addr)); |
2196 __ far_call(RuntimeAddress(copyfunc_addr)); |
2201 } |
|
2202 |
2197 |
2203 __ cbz(r0, *stub->continuation()); |
2198 __ cbz(r0, *stub->continuation()); |
2204 |
2199 |
2205 // Reload values from the stack so they are where the stub |
2200 // Reload values from the stack so they are where the stub |
2206 // expects them. |
2201 // expects them. |
2207 __ ldp(dst, dst_pos, Address(sp, 0*BytesPerWord)); |
2202 __ ldp(dst, dst_pos, Address(sp, 0*BytesPerWord)); |
2208 __ ldp(length, src_pos, Address(sp, 2*BytesPerWord)); |
2203 __ ldp(length, src_pos, Address(sp, 2*BytesPerWord)); |
2209 __ ldr(src, Address(sp, 4*BytesPerWord)); |
2204 __ ldr(src, Address(sp, 4*BytesPerWord)); |
2210 |
2205 |
2211 if (copyfunc_addr != NULL) { |
2206 // r0 is -1^K where K == partial copied count |
2212 // r0 is -1^K where K == partial copied count |
2207 __ eonw(rscratch1, r0, 0); |
2213 __ eonw(rscratch1, r0, 0); |
2208 // adjust length down and src/end pos up by partial copied count |
2214 // adjust length down and src/end pos up by partial copied count |
2209 __ subw(length, length, rscratch1); |
2215 __ subw(length, length, rscratch1); |
2210 __ addw(src_pos, src_pos, rscratch1); |
2216 __ addw(src_pos, src_pos, rscratch1); |
2211 __ addw(dst_pos, dst_pos, rscratch1); |
2217 __ addw(dst_pos, dst_pos, rscratch1); |
|
2218 } |
|
2219 __ b(*stub->entry()); |
2212 __ b(*stub->entry()); |
2220 |
2213 |
2221 __ bind(*stub->continuation()); |
2214 __ bind(*stub->continuation()); |
2222 return; |
2215 return; |
2223 } |
2216 } |