2078
2079 StubRoutines::_unsafe_arraycopy =
2080 generate_unsafe_copy("unsafe_arraycopy",
2081 entry_jbyte_arraycopy,
2082 entry_jshort_arraycopy,
2083 entry_jint_arraycopy,
2084 entry_jlong_arraycopy);
2085
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", "log");
2099 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
2100
2101 __ fld_d(Address(rsp, 4));
2102 __ flog();
2103 __ ret(0);
2104 }
2105 {
2106 StubCodeMark mark(this, "StubRoutines", "log10");
2107 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
2108
2109 __ fld_d(Address(rsp, 4));
2110 __ flog10();
2111 __ ret(0);
2112 }
2113 {
2114 StubCodeMark mark(this, "StubRoutines", "sin");
2115 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
2116
2117 __ fld_d(Address(rsp, 4));
2118 __ trigfunc('s');
2119 __ ret(0);
2120 }
2121 {
2122 StubCodeMark mark(this, "StubRoutines", "cos");
2123 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
2124
2125 __ fld_d(Address(rsp, 4));
3048 const XMMRegister x2 = xmm2;
3049 const XMMRegister x3 = xmm3;
3050
3051 const XMMRegister x4 = xmm4;
3052 const XMMRegister x5 = xmm5;
3053 const XMMRegister x6 = xmm6;
3054 const XMMRegister x7 = xmm7;
3055
3056 const Register tmp = rbx;
3057
3058 BLOCK_COMMENT("Entry:");
3059 __ enter(); // required for proper stackwalking of RuntimeStub frame
3060 __ fast_exp(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp);
3061 __ leave(); // required for proper stackwalking of RuntimeStub frame
3062 __ ret(0);
3063
3064 return start;
3065
3066 }
3067
3068
3069 // Safefetch stubs.
3070 void generate_safefetch(const char* name, int size, address* entry,
3071 address* fault_pc, address* continuation_pc) {
3072 // safefetch signatures:
3073 // int SafeFetch32(int* adr, int errValue);
3074 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
3075
3076 StubCodeMark mark(this, "StubRoutines", name);
3077
3078 // Entry point, pc or function descriptor.
3079 *entry = __ pc();
3080
3081 __ movl(rax, Address(rsp, 0x8));
3082 __ movl(rcx, Address(rsp, 0x4));
3083 // Load *adr into eax, may fault.
3084 *fault_pc = __ pc();
3085 switch (size) {
3086 case 4:
3087 // int32_t
3271 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG,
3272 CAST_FROM_FN_PTR(address, SharedRuntime::d2l));
3273
3274 // Build this early so it's available for the interpreter
3275 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
3276
3277 if (UseCRC32Intrinsics) {
3278 // set table address before stub generation which use it
3279 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
3280 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
3281 }
3282
3283 if (UseCRC32CIntrinsics) {
3284 bool supports_clmul = VM_Version::supports_clmul();
3285 StubRoutines::x86::generate_CRC32C_table(supports_clmul);
3286 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
3287 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
3288 }
3289 if (VM_Version::supports_sse2()) {
3290 StubRoutines::_dexp = generate_libmExp();
3291 }
3292 }
3293
3294
3295 void generate_all() {
3296 // Generates all stubs and initializes the entry points
3297
3298 // These entry points require SharedInfo::stack0 to be set up in non-core builds
3299 // and need to be relocatable, so they each fabricate a RuntimeStub internally.
3300 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
3301 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
3302 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
3303
3304 //------------------------------------------------------------------------------------------------------------------------
3305 // entry points that are platform specific
3306
3307 // support for verify_oop (must happen after universe_init)
3308 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
3309
3310 // arraycopy stubs used by compilers
|
2078
2079 StubRoutines::_unsafe_arraycopy =
2080 generate_unsafe_copy("unsafe_arraycopy",
2081 entry_jbyte_arraycopy,
2082 entry_jshort_arraycopy,
2083 entry_jint_arraycopy,
2084 entry_jlong_arraycopy);
2085
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));
3040 const XMMRegister x2 = xmm2;
3041 const XMMRegister x3 = xmm3;
3042
3043 const XMMRegister x4 = xmm4;
3044 const XMMRegister x5 = xmm5;
3045 const XMMRegister x6 = xmm6;
3046 const XMMRegister x7 = xmm7;
3047
3048 const Register tmp = rbx;
3049
3050 BLOCK_COMMENT("Entry:");
3051 __ enter(); // required for proper stackwalking of RuntimeStub frame
3052 __ fast_exp(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp);
3053 __ leave(); // required for proper stackwalking of RuntimeStub frame
3054 __ ret(0);
3055
3056 return start;
3057
3058 }
3059
3060 address generate_libmLog() {
3061 address start = __ pc();
3062
3063 const XMMRegister x0 = xmm0;
3064 const XMMRegister x1 = xmm1;
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
3289 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG,
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
|