2086 StubRoutines::_generic_arraycopy = 2087 generate_generic_copy("generic_arraycopy", 2088 entry_jbyte_arraycopy, 2089 entry_jshort_arraycopy, 2090 entry_jint_arraycopy, 2091 entry_oop_arraycopy, 2092 entry_jlong_arraycopy, 2093 entry_checkcast_arraycopy); 2094 } 2095 2096 void generate_math_stubs() { 2097 { 2098 StubCodeMark mark(this, "StubRoutines", "log10"); 2099 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 2100 2101 __ fld_d(Address(rsp, 4)); 2102 __ flog10(); 2103 __ ret(0); 2104 } 2105 { 2106 StubCodeMark mark(this, "StubRoutines", "sin"); 2107 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc(); 2108 2109 __ fld_d(Address(rsp, 4)); 2110 __ trigfunc('s'); 2111 __ ret(0); 2112 } 2113 { 2114 StubCodeMark mark(this, "StubRoutines", "cos"); 2115 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc(); 2116 2117 __ fld_d(Address(rsp, 4)); 2118 __ trigfunc('c'); 2119 __ ret(0); 2120 } 2121 { 2122 StubCodeMark mark(this, "StubRoutines", "tan"); 2123 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 2124 2125 __ fld_d(Address(rsp, 4)); 2126 __ trigfunc('t'); 2127 __ ret(0); 2128 } 2129 { 2130 StubCodeMark mark(this, "StubRoutines", "pow"); 2131 StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc(); 2132 2133 __ fld_d(Address(rsp, 12)); 2134 __ fld_d(Address(rsp, 4)); 2135 __ pow_with_fallback(0); 2136 __ ret(0); 2137 } 2138 } 2139 2140 // AES intrinsic stubs 2141 enum {AESBlockSize = 16}; 3065 const XMMRegister x2 = xmm2; 3066 const XMMRegister x3 = xmm3; 3067 3068 const XMMRegister x4 = xmm4; 3069 const XMMRegister x5 = xmm5; 3070 const XMMRegister x6 = xmm6; 3071 const XMMRegister x7 = xmm7; 3072 3073 const Register tmp = rbx; 3074 3075 BLOCK_COMMENT("Entry:"); 3076 __ enter(); // required for proper stackwalking of RuntimeStub frame 3077 __ fast_log(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp); 3078 __ leave(); // required for proper stackwalking of RuntimeStub frame 3079 __ ret(0); 3080 3081 return start; 3082 3083 } 3084 3085 3086 3087 // Safefetch stubs. 3088 void generate_safefetch(const char* name, int size, address* entry, 3089 address* fault_pc, address* continuation_pc) { 3090 // safefetch signatures: 3091 // int SafeFetch32(int* adr, int errValue); 3092 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); 3093 3094 StubCodeMark mark(this, "StubRoutines", name); 3095 3096 // Entry point, pc or function descriptor. 3097 *entry = __ pc(); 3098 3099 __ movl(rax, Address(rsp, 0x8)); 3100 __ movl(rcx, Address(rsp, 0x4)); 3101 // Load *adr into eax, may fault. 3102 *fault_pc = __ pc(); 3103 switch (size) { 3104 case 4: 3105 // int32_t 3290 CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); 3291 3292 // Build this early so it's available for the interpreter 3293 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); 3294 3295 if (UseCRC32Intrinsics) { 3296 // set table address before stub generation which use it 3297 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 3298 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 3299 } 3300 3301 if (UseCRC32CIntrinsics) { 3302 bool supports_clmul = VM_Version::supports_clmul(); 3303 StubRoutines::x86::generate_CRC32C_table(supports_clmul); 3304 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; 3305 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); 3306 } 3307 if (VM_Version::supports_sse2()) { 3308 StubRoutines::_dexp = generate_libmExp(); 3309 StubRoutines::_dlog = generate_libmLog(); 3310 } 3311 } 3312 3313 3314 void generate_all() { 3315 // Generates all stubs and initializes the entry points 3316 3317 // These entry points require SharedInfo::stack0 to be set up in non-core builds 3318 // and need to be relocatable, so they each fabricate a RuntimeStub internally. 3319 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError)); 3320 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError)); 3321 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call)); 3322 3323 //------------------------------------------------------------------------------------------------------------------------ 3324 // entry points that are platform specific 3325 3326 // support for verify_oop (must happen after universe_init) 3327 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); 3328 3329 // arraycopy stubs used by compilers | 2086 StubRoutines::_generic_arraycopy = 2087 generate_generic_copy("generic_arraycopy", 2088 entry_jbyte_arraycopy, 2089 entry_jshort_arraycopy, 2090 entry_jint_arraycopy, 2091 entry_oop_arraycopy, 2092 entry_jlong_arraycopy, 2093 entry_checkcast_arraycopy); 2094 } 2095 2096 void generate_math_stubs() { 2097 { 2098 StubCodeMark mark(this, "StubRoutines", "log10"); 2099 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 2100 2101 __ fld_d(Address(rsp, 4)); 2102 __ flog10(); 2103 __ ret(0); 2104 } 2105 { 2106 StubCodeMark mark(this, "StubRoutines", "tan"); 2107 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 2108 2109 __ fld_d(Address(rsp, 4)); 2110 __ trigfunc('t'); 2111 __ ret(0); 2112 } 2113 { 2114 StubCodeMark mark(this, "StubRoutines", "pow"); 2115 StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc(); 2116 2117 __ fld_d(Address(rsp, 12)); 2118 __ fld_d(Address(rsp, 4)); 2119 __ pow_with_fallback(0); 2120 __ ret(0); 2121 } 2122 } 2123 2124 // AES intrinsic stubs 2125 enum {AESBlockSize = 16}; 3049 const XMMRegister x2 = xmm2; 3050 const XMMRegister x3 = xmm3; 3051 3052 const XMMRegister x4 = xmm4; 3053 const XMMRegister x5 = xmm5; 3054 const XMMRegister x6 = xmm6; 3055 const XMMRegister x7 = xmm7; 3056 3057 const Register tmp = rbx; 3058 3059 BLOCK_COMMENT("Entry:"); 3060 __ enter(); // required for proper stackwalking of RuntimeStub frame 3061 __ fast_log(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp); 3062 __ leave(); // required for proper stackwalking of RuntimeStub frame 3063 __ ret(0); 3064 3065 return start; 3066 3067 } 3068 3069 address generate_libm_reduce_pi04l() { 3070 address start = __ pc(); 3071 3072 BLOCK_COMMENT("Entry:"); 3073 __ libm_reduce_pi04l(rax, rcx, rdx, rbx, rsi, rdi, rbp, rsp); 3074 3075 return start; 3076 3077 } 3078 3079 address generate_libm_sin_cos_huge() { 3080 address start = __ pc(); 3081 3082 const XMMRegister x0 = xmm0; 3083 const XMMRegister x1 = xmm1; 3084 3085 BLOCK_COMMENT("Entry:"); 3086 __ libm_sincos_huge(x0, x1, rax, rcx, rdx, rbx, rsi, rdi, rbp, rsp); 3087 3088 return start; 3089 3090 } 3091 3092 address generate_libmSin() { 3093 address start = __ pc(); 3094 3095 const XMMRegister x0 = xmm0; 3096 const XMMRegister x1 = xmm1; 3097 const XMMRegister x2 = xmm2; 3098 const XMMRegister x3 = xmm3; 3099 3100 const XMMRegister x4 = xmm4; 3101 const XMMRegister x5 = xmm5; 3102 const XMMRegister x6 = xmm6; 3103 const XMMRegister x7 = xmm7; 3104 3105 BLOCK_COMMENT("Entry:"); 3106 __ enter(); // required for proper stackwalking of RuntimeStub frame 3107 __ fast_sin(x0, x1, x2, x3, x4, x5, x6, x7, rax, rbx, rdx); 3108 __ leave(); // required for proper stackwalking of RuntimeStub frame 3109 __ ret(0); 3110 3111 return start; 3112 3113 } 3114 3115 address generate_libmCos() { 3116 address start = __ pc(); 3117 3118 const XMMRegister x0 = xmm0; 3119 const XMMRegister x1 = xmm1; 3120 const XMMRegister x2 = xmm2; 3121 const XMMRegister x3 = xmm3; 3122 3123 const XMMRegister x4 = xmm4; 3124 const XMMRegister x5 = xmm5; 3125 const XMMRegister x6 = xmm6; 3126 const XMMRegister x7 = xmm7; 3127 3128 const Register tmp = rbx; 3129 3130 BLOCK_COMMENT("Entry:"); 3131 __ enter(); // required for proper stackwalking of RuntimeStub frame 3132 __ fast_cos(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp); 3133 __ leave(); // required for proper stackwalking of RuntimeStub frame 3134 __ ret(0); 3135 3136 return start; 3137 3138 } 3139 3140 // Safefetch stubs. 3141 void generate_safefetch(const char* name, int size, address* entry, 3142 address* fault_pc, address* continuation_pc) { 3143 // safefetch signatures: 3144 // int SafeFetch32(int* adr, int errValue); 3145 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); 3146 3147 StubCodeMark mark(this, "StubRoutines", name); 3148 3149 // Entry point, pc or function descriptor. 3150 *entry = __ pc(); 3151 3152 __ movl(rax, Address(rsp, 0x8)); 3153 __ movl(rcx, Address(rsp, 0x4)); 3154 // Load *adr into eax, may fault. 3155 *fault_pc = __ pc(); 3156 switch (size) { 3157 case 4: 3158 // int32_t 3343 CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); 3344 3345 // Build this early so it's available for the interpreter 3346 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); 3347 3348 if (UseCRC32Intrinsics) { 3349 // set table address before stub generation which use it 3350 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 3351 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 3352 } 3353 3354 if (UseCRC32CIntrinsics) { 3355 bool supports_clmul = VM_Version::supports_clmul(); 3356 StubRoutines::x86::generate_CRC32C_table(supports_clmul); 3357 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; 3358 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); 3359 } 3360 if (VM_Version::supports_sse2()) { 3361 StubRoutines::_dexp = generate_libmExp(); 3362 StubRoutines::_dlog = generate_libmLog(); 3363 if (UseLibmSinIntrinsic || UseLibmCosIntrinsic) { 3364 StubRoutines::_dlibm_reduce_pi04l = generate_libm_reduce_pi04l(); 3365 StubRoutines::_dlibm_sin_cos_huge = generate_libm_sin_cos_huge(); 3366 } 3367 if (UseLibmSinIntrinsic) { 3368 StubRoutines::_dsin = generate_libmSin(); 3369 } 3370 if (UseLibmCosIntrinsic) { 3371 StubRoutines::_dcos = generate_libmCos(); 3372 } 3373 } 3374 } 3375 3376 3377 void generate_all() { 3378 // Generates all stubs and initializes the entry points 3379 3380 // These entry points require SharedInfo::stack0 to be set up in non-core builds 3381 // and need to be relocatable, so they each fabricate a RuntimeStub internally. 3382 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError)); 3383 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError)); 3384 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call)); 3385 3386 //------------------------------------------------------------------------------------------------------------------------ 3387 // entry points that are platform specific 3388 3389 // support for verify_oop (must happen after universe_init) 3390 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); 3391 3392 // arraycopy stubs used by compilers |