3675 __ ret(0); |
3675 __ ret(0); |
3676 |
3676 |
3677 return start; |
3677 return start; |
3678 } |
3678 } |
3679 |
3679 |
|
3680 |
|
3681 /** |
|
3682 * Arguments: |
|
3683 * |
|
3684 * Input: |
|
3685 * c_rarg0 - x address |
|
3686 * c_rarg1 - x length |
|
3687 * c_rarg2 - y address |
|
3688 * c_rarg3 - y lenth |
|
3689 * not Win64 |
|
3690 * c_rarg4 - z address |
|
3691 * c_rarg5 - z length |
|
3692 * Win64 |
|
3693 * rsp+40 - z address |
|
3694 * rsp+48 - z length |
|
3695 */ |
|
3696 address generate_multiplyToLen() { |
|
3697 __ align(CodeEntryAlignment); |
|
3698 StubCodeMark mark(this, "StubRoutines", "multiplyToLen"); |
|
3699 |
|
3700 address start = __ pc(); |
|
3701 // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) |
|
3702 // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) |
|
3703 const Register x = rdi; |
|
3704 const Register xlen = rax; |
|
3705 const Register y = rsi; |
|
3706 const Register ylen = rcx; |
|
3707 const Register z = r8; |
|
3708 const Register zlen = r11; |
|
3709 |
|
3710 // Next registers will be saved on stack in multiply_to_len(). |
|
3711 const Register tmp1 = r12; |
|
3712 const Register tmp2 = r13; |
|
3713 const Register tmp3 = r14; |
|
3714 const Register tmp4 = r15; |
|
3715 const Register tmp5 = rbx; |
|
3716 |
|
3717 BLOCK_COMMENT("Entry:"); |
|
3718 __ enter(); // required for proper stackwalking of RuntimeStub frame |
|
3719 |
|
3720 #ifndef _WIN64 |
|
3721 __ movptr(zlen, r9); // Save r9 in r11 - zlen |
|
3722 #endif |
|
3723 setup_arg_regs(4); // x => rdi, xlen => rsi, y => rdx |
|
3724 // ylen => rcx, z => r8, zlen => r11 |
|
3725 // r9 and r10 may be used to save non-volatile registers |
|
3726 #ifdef _WIN64 |
|
3727 // last 2 arguments (#4, #5) are on stack on Win64 |
|
3728 __ movptr(z, Address(rsp, 6 * wordSize)); |
|
3729 __ movptr(zlen, Address(rsp, 7 * wordSize)); |
|
3730 #endif |
|
3731 |
|
3732 __ movptr(xlen, rsi); |
|
3733 __ movptr(y, rdx); |
|
3734 __ multiply_to_len(x, xlen, y, ylen, z, zlen, tmp1, tmp2, tmp3, tmp4, tmp5); |
|
3735 |
|
3736 restore_arg_regs(); |
|
3737 |
|
3738 __ leave(); // required for proper stackwalking of RuntimeStub frame |
|
3739 __ ret(0); |
|
3740 |
|
3741 return start; |
|
3742 } |
|
3743 |
3680 #undef __ |
3744 #undef __ |
3681 #define __ masm-> |
3745 #define __ masm-> |
3682 |
3746 |
3683 // Continuation point for throwing of implicit exceptions that are |
3747 // Continuation point for throwing of implicit exceptions that are |
3684 // not handled in the current activation. Fabricates an exception |
3748 // not handled in the current activation. Fabricates an exception |
3915 &StubRoutines::_safefetch32_fault_pc, |
3979 &StubRoutines::_safefetch32_fault_pc, |
3916 &StubRoutines::_safefetch32_continuation_pc); |
3980 &StubRoutines::_safefetch32_continuation_pc); |
3917 generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, |
3981 generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, |
3918 &StubRoutines::_safefetchN_fault_pc, |
3982 &StubRoutines::_safefetchN_fault_pc, |
3919 &StubRoutines::_safefetchN_continuation_pc); |
3983 &StubRoutines::_safefetchN_continuation_pc); |
|
3984 #ifdef COMPILER2 |
|
3985 if (UseMultiplyToLenIntrinsic) { |
|
3986 StubRoutines::_multiplyToLen = generate_multiplyToLen(); |
|
3987 } |
|
3988 #endif |
3920 } |
3989 } |
3921 |
3990 |
3922 public: |
3991 public: |
3923 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { |
3992 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { |
3924 if (all) { |
3993 if (all) { |