2924 Address buf_arg(rbp, 8 + 4); 2925 Address len_arg(rbp, 8 + 8); 2926 2927 // Load up: 2928 __ movl(crc, crc_arg); 2929 __ movptr(buf, buf_arg); 2930 __ movl(len, len_arg); 2931 2932 __ kernel_crc32(crc, buf, len, table, tmp); 2933 2934 __ movl(rax, crc); 2935 __ pop(rbx); 2936 __ pop(rdi); 2937 __ pop(rsi); 2938 __ leave(); // required for proper stackwalking of RuntimeStub frame 2939 __ ret(0); 2940 2941 return start; 2942 } 2943 2944 // Safefetch stubs. 2945 void generate_safefetch(const char* name, int size, address* entry, 2946 address* fault_pc, address* continuation_pc) { 2947 // safefetch signatures: 2948 // int SafeFetch32(int* adr, int errValue); 2949 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); 2950 2951 StubCodeMark mark(this, "StubRoutines", name); 2952 2953 // Entry point, pc or function descriptor. 2954 *entry = __ pc(); 2955 2956 __ movl(rax, Address(rsp, 0x8)); 2957 __ movl(rcx, Address(rsp, 0x4)); 2958 // Load *adr into eax, may fault. 2959 *fault_pc = __ pc(); 2960 switch (size) { 2961 case 4: 2962 // int32_t 2963 __ movl(rax, Address(rcx, 0)); 3136 StubRoutines::_handler_for_unsafe_access_entry = 3137 generate_handler_for_unsafe_access(); 3138 3139 // platform dependent 3140 create_control_words(); 3141 3142 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); 3143 StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); 3144 StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT, 3145 CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); 3146 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, 3147 CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); 3148 3149 // Build this early so it's available for the interpreter 3150 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); 3151 3152 if (UseCRC32Intrinsics) { 3153 // set table address before stub generation which use it 3154 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 3155 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 3156 } 3157 } 3158 3159 3160 void generate_all() { 3161 // Generates all stubs and initializes the entry points 3162 3163 // These entry points require SharedInfo::stack0 to be set up in non-core builds 3164 // and need to be relocatable, so they each fabricate a RuntimeStub internally. 3165 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError)); 3166 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError)); 3167 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call)); 3168 3169 //------------------------------------------------------------------------------------------------------------------------ 3170 // entry points that are platform specific 3171 3172 // support for verify_oop (must happen after universe_init) 3173 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); 3174 3175 // arraycopy stubs used by compilers | 2924 Address buf_arg(rbp, 8 + 4); 2925 Address len_arg(rbp, 8 + 8); 2926 2927 // Load up: 2928 __ movl(crc, crc_arg); 2929 __ movptr(buf, buf_arg); 2930 __ movl(len, len_arg); 2931 2932 __ kernel_crc32(crc, buf, len, table, tmp); 2933 2934 __ movl(rax, crc); 2935 __ pop(rbx); 2936 __ pop(rdi); 2937 __ pop(rsi); 2938 __ leave(); // required for proper stackwalking of RuntimeStub frame 2939 __ ret(0); 2940 2941 return start; 2942 } 2943 2944 /** 2945 * Arguments: 2946 * 2947 * Inputs: 2948 * rsp(4) - int crc 2949 * rsp(8) - byte* buf 2950 * rsp(12) - int length 2951 * rsp(16) - table_start - optional (present only when doing a library_calll, 2952 * not used by x86 algorithm) 2953 * 2954 * Ouput: 2955 * rax - int crc result 2956 */ 2957 address generate_updateBytesCRC32C(bool IsPclmulqdqSupported) { 2958 assert(UseCRC32CIntrinsics, "need SSE4_2"); 2959 __ align(CodeEntryAlignment); 2960 StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C"); 2961 address start = __ pc(); 2962 const Register crc = rax; // crc 2963 const Register buf = rcx; // source java byte array address 2964 const Register len = rdx; // length 2965 const Register D = rbx; 2966 const Register G = rsi; 2967 const Register H = rdi; 2968 const Register empty = 0; // will never be used, in order not 2969 // to change a signature for crc32c_IPL_Alg2Alt2Fast 2970 // between 64/32 I'm just keeping it here 2971 assert_different_registers(crc, buf, len, D, G, H); 2972 2973 BLOCK_COMMENT("Entry:"); 2974 __ enter(); // required for proper stackwalking of RuntimeStub frame 2975 Address crc_arg(rsp, 4 + 4 + 0); // ESP+4 + 2976 // we need to add additional 4 because __ enter 2977 // have just pushed ebp on a stack 2978 Address buf_arg(rsp, 4 + 4 + 4); 2979 Address len_arg(rsp, 4 + 4 + 8); 2980 // Load up: 2981 __ movl(crc, crc_arg); 2982 __ movl(buf, buf_arg); 2983 __ movl(len, len_arg); 2984 __ push(D); 2985 __ push(G); 2986 __ push(H); 2987 __ crc32c_IPL_Alg2Alt2Fast(crc, buf, len, 2988 D, G, H, 2989 empty, empty, empty, 2990 xmm0, xmm1, xmm2, 2991 IsPclmulqdqSupported); 2992 __ pop(H); 2993 __ pop(G); 2994 __ pop(D); 2995 __ leave(); // required for proper stackwalking of RuntimeStub frame 2996 __ ret(0); 2997 2998 return start; 2999 } 3000 3001 // Safefetch stubs. 3002 void generate_safefetch(const char* name, int size, address* entry, 3003 address* fault_pc, address* continuation_pc) { 3004 // safefetch signatures: 3005 // int SafeFetch32(int* adr, int errValue); 3006 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); 3007 3008 StubCodeMark mark(this, "StubRoutines", name); 3009 3010 // Entry point, pc or function descriptor. 3011 *entry = __ pc(); 3012 3013 __ movl(rax, Address(rsp, 0x8)); 3014 __ movl(rcx, Address(rsp, 0x4)); 3015 // Load *adr into eax, may fault. 3016 *fault_pc = __ pc(); 3017 switch (size) { 3018 case 4: 3019 // int32_t 3020 __ movl(rax, Address(rcx, 0)); 3193 StubRoutines::_handler_for_unsafe_access_entry = 3194 generate_handler_for_unsafe_access(); 3195 3196 // platform dependent 3197 create_control_words(); 3198 3199 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); 3200 StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); 3201 StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT, 3202 CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); 3203 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, 3204 CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); 3205 3206 // Build this early so it's available for the interpreter 3207 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); 3208 3209 if (UseCRC32Intrinsics) { 3210 // set table address before stub generation which use it 3211 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 3212 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 3213 } 3214 3215 if (UseCRC32CIntrinsics) { 3216 bool supports_clmul; 3217 StubRoutines::x86::GenerateCRC32CTable(supports_clmul = VM_Version::supports_clmul()); 3218 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; 3219 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); 3220 } 3221 } 3222 3223 3224 void generate_all() { 3225 // Generates all stubs and initializes the entry points 3226 3227 // These entry points require SharedInfo::stack0 to be set up in non-core builds 3228 // and need to be relocatable, so they each fabricate a RuntimeStub internally. 3229 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError)); 3230 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError)); 3231 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call)); 3232 3233 //------------------------------------------------------------------------------------------------------------------------ 3234 // entry points that are platform specific 3235 3236 // support for verify_oop (must happen after universe_init) 3237 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); 3238 3239 // arraycopy stubs used by compilers |