3111 // For the moment until C1 gets the new register allocator I just force all the |
3111 // For the moment until C1 gets the new register allocator I just force all the |
3112 // args to the right place (except the register args) and then on the back side |
3112 // args to the right place (except the register args) and then on the back side |
3113 // reload the register args properly if we go slow path. Yuck |
3113 // reload the register args properly if we go slow path. Yuck |
3114 |
3114 |
3115 // These are proper for the calling convention |
3115 // These are proper for the calling convention |
3116 |
|
3117 store_parameter(length, 2); |
3116 store_parameter(length, 2); |
3118 store_parameter(dst_pos, 1); |
3117 store_parameter(dst_pos, 1); |
3119 store_parameter(dst, 0); |
3118 store_parameter(dst, 0); |
3120 |
3119 |
3121 // these are just temporary placements until we need to reload |
3120 // these are just temporary placements until we need to reload |
3349 jint objArray_lh = Klass::array_layout_helper(T_OBJECT); |
3348 jint objArray_lh = Klass::array_layout_helper(T_OBJECT); |
3350 __ cmpl(klass_lh_addr, objArray_lh); |
3349 __ cmpl(klass_lh_addr, objArray_lh); |
3351 __ jcc(Assembler::notEqual, *stub->entry()); |
3350 __ jcc(Assembler::notEqual, *stub->entry()); |
3352 } |
3351 } |
3353 |
3352 |
|
3353 // Spill because stubs can use any register they like and it's |
|
3354 // easier to restore just those that we care about. |
|
3355 store_parameter(dst, 0); |
|
3356 store_parameter(dst_pos, 1); |
|
3357 store_parameter(length, 2); |
|
3358 store_parameter(src_pos, 3); |
|
3359 store_parameter(src, 4); |
|
3360 |
3354 #ifndef _LP64 |
3361 #ifndef _LP64 |
3355 // save caller save registers |
|
3356 store_parameter(rax, 2); |
|
3357 store_parameter(rcx, 1); |
|
3358 store_parameter(rdx, 0); |
|
3359 |
|
3360 __ movptr(tmp, dst_klass_addr); |
3362 __ movptr(tmp, dst_klass_addr); |
3361 __ movptr(tmp, Address(tmp, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); |
3363 __ movptr(tmp, Address(tmp, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); |
3362 __ push(tmp); |
3364 __ push(tmp); |
3363 __ movl(tmp, Address(tmp, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc))); |
3365 __ movl(tmp, Address(tmp, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc))); |
3364 __ push(tmp); |
3366 __ push(tmp); |
3369 __ push(tmp); |
3371 __ push(tmp); |
3370 |
3372 |
3371 __ call_VM_leaf(copyfunc_addr, 5); |
3373 __ call_VM_leaf(copyfunc_addr, 5); |
3372 #else |
3374 #else |
3373 __ movl2ptr(length, length); //higher 32bits must be null |
3375 __ movl2ptr(length, length); //higher 32bits must be null |
3374 |
|
3375 // save caller save registers: copy them to callee save registers |
|
3376 __ mov(rbx, rdx); |
|
3377 __ mov(r13, r8); |
|
3378 __ mov(r14, r9); |
|
3379 #ifndef _WIN64 |
|
3380 store_parameter(rsi, 1); |
|
3381 store_parameter(rcx, 0); |
|
3382 // on WIN64 other incoming parameters are in rdi and rsi saved |
|
3383 // across the call |
|
3384 #endif |
|
3385 |
3376 |
3386 __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3377 __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3387 assert_different_registers(c_rarg0, dst, dst_pos, length); |
3378 assert_different_registers(c_rarg0, dst, dst_pos, length); |
3388 __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3379 __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3389 assert_different_registers(c_rarg1, dst, length); |
3380 assert_different_registers(c_rarg1, dst, length); |
3430 |
3421 |
3431 __ mov(tmp, rax); |
3422 __ mov(tmp, rax); |
3432 |
3423 |
3433 __ xorl(tmp, -1); |
3424 __ xorl(tmp, -1); |
3434 |
3425 |
3435 #ifndef _LP64 |
3426 // Restore previously spilled arguments |
3436 // restore caller save registers |
3427 __ movptr (dst, Address(rsp, 0*BytesPerWord)); |
3437 assert_different_registers(tmp, rdx, rcx, rax); // result of stub will be lost |
3428 __ movptr (dst_pos, Address(rsp, 1*BytesPerWord)); |
3438 __ movptr(rdx, Address(rsp, 0*BytesPerWord)); |
3429 __ movptr (length, Address(rsp, 2*BytesPerWord)); |
3439 __ movptr(rcx, Address(rsp, 1*BytesPerWord)); |
3430 __ movptr (src_pos, Address(rsp, 3*BytesPerWord)); |
3440 __ movptr(rax, Address(rsp, 2*BytesPerWord)); |
3431 __ movptr (src, Address(rsp, 4*BytesPerWord)); |
3441 #else |
3432 |
3442 // restore caller save registers |
|
3443 __ mov(rdx, rbx); |
|
3444 __ mov(r8, r13); |
|
3445 __ mov(r9, r14); |
|
3446 #ifndef _WIN64 |
|
3447 assert_different_registers(tmp, rdx, r8, r9, rcx, rsi); // result of stub will be lost |
|
3448 __ movptr(rcx, Address(rsp, 0*BytesPerWord)); |
|
3449 __ movptr(rsi, Address(rsp, 1*BytesPerWord)); |
|
3450 #else |
|
3451 assert_different_registers(tmp, rdx, r8, r9); // result of stub will be lost |
|
3452 #endif |
|
3453 #endif |
|
3454 |
3433 |
3455 __ subl(length, tmp); |
3434 __ subl(length, tmp); |
3456 __ addl(src_pos, tmp); |
3435 __ addl(src_pos, tmp); |
3457 __ addl(dst_pos, tmp); |
3436 __ addl(dst_pos, tmp); |
3458 } |
3437 } |