2970 2971 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit; 2972 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit; 2973 } 2974 2975 void generate_math_stubs() { 2976 { 2977 StubCodeMark mark(this, "StubRoutines", "log10"); 2978 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 2979 2980 __ subq(rsp, 8); 2981 __ movdbl(Address(rsp, 0), xmm0); 2982 __ fld_d(Address(rsp, 0)); 2983 __ flog10(); 2984 __ fstp_d(Address(rsp, 0)); 2985 __ movdbl(xmm0, Address(rsp, 0)); 2986 __ addq(rsp, 8); 2987 __ ret(0); 2988 } 2989 { 2990 StubCodeMark mark(this, "StubRoutines", "sin"); 2991 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc(); 2992 2993 __ subq(rsp, 8); 2994 __ movdbl(Address(rsp, 0), xmm0); 2995 __ fld_d(Address(rsp, 0)); 2996 __ trigfunc('s'); 2997 __ fstp_d(Address(rsp, 0)); 2998 __ movdbl(xmm0, Address(rsp, 0)); 2999 __ addq(rsp, 8); 3000 __ ret(0); 3001 } 3002 { 3003 StubCodeMark mark(this, "StubRoutines", "cos"); 3004 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc(); 3005 3006 __ subq(rsp, 8); 3007 __ movdbl(Address(rsp, 0), xmm0); 3008 __ fld_d(Address(rsp, 0)); 3009 __ trigfunc('c'); 3010 __ fstp_d(Address(rsp, 0)); 3011 __ movdbl(xmm0, Address(rsp, 0)); 3012 __ addq(rsp, 8); 3013 __ ret(0); 3014 } 3015 { 3016 StubCodeMark mark(this, "StubRoutines", "tan"); 3017 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 3018 3019 __ subq(rsp, 8); 3020 __ movdbl(Address(rsp, 0), xmm0); 3021 __ fld_d(Address(rsp, 0)); 3022 __ trigfunc('t'); 3023 __ fstp_d(Address(rsp, 0)); 3024 __ movdbl(xmm0, Address(rsp, 0)); 3025 __ addq(rsp, 8); 3026 __ ret(0); 3027 } 3028 { 3029 StubCodeMark mark(this, "StubRoutines", "pow"); 3030 StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc(); 3031 3032 __ subq(rsp, 8); 3033 __ movdbl(Address(rsp, 0), xmm1); 3034 __ fld_d(Address(rsp, 0)); 3035 __ movdbl(Address(rsp, 0), xmm0); 4218 __ subptr(rsp, 4 * wordSize); 4219 __ movdqu(Address(rsp, 0), xmm6); 4220 __ movdqu(Address(rsp, 2 * wordSize), xmm7); 4221 #endif 4222 __ fast_log(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2); 4223 4224 #ifdef _WIN64 4225 // restore xmm regs belonging to calling function 4226 __ movdqu(xmm6, Address(rsp, 0)); 4227 __ movdqu(xmm7, Address(rsp, 2 * wordSize)); 4228 __ addptr(rsp, 4 * wordSize); 4229 #endif 4230 4231 __ leave(); // required for proper stackwalking of RuntimeStub frame 4232 __ ret(0); 4233 4234 return start; 4235 4236 } 4237 4238 4239 #undef __ 4240 #define __ masm-> 4241 4242 // Continuation point for throwing of implicit exceptions that are 4243 // not handled in the current activation. Fabricates an exception 4244 // oop and initiates normal exception dispatching in this 4245 // frame. Since we need to preserve callee-saved values (currently 4246 // only for C2, but done for C1 as well) we need a callee-saved oop 4247 // map and therefore have to make these stubs into RuntimeStubs 4248 // rather than BufferBlobs. If the compiler needs all registers to 4249 // be preserved between the fault point and the exception handler 4250 // then it must assume responsibility for that in 4251 // AbstractCompiler::continuation_for_implicit_null_exception or 4252 // continuation_for_implicit_division_by_zero_exception. All other 4253 // implicit exceptions (e.g., NullPointerException or 4254 // AbstractMethodError on entry) are either at call sites or 4255 // otherwise assume that stack unwinding will be initiated, so 4256 // caller saved registers were assumed volatile in the compiler. 4257 address generate_throw_exception(const char* name, 4408 StubRoutines::_throw_StackOverflowError_entry = 4409 generate_throw_exception("StackOverflowError throw_exception", 4410 CAST_FROM_FN_PTR(address, 4411 SharedRuntime:: 4412 throw_StackOverflowError)); 4413 if (UseCRC32Intrinsics) { 4414 // set table address before stub generation which use it 4415 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 4416 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 4417 } 4418 4419 if (UseCRC32CIntrinsics) { 4420 bool supports_clmul = VM_Version::supports_clmul(); 4421 StubRoutines::x86::generate_CRC32C_table(supports_clmul); 4422 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; 4423 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); 4424 } 4425 if (VM_Version::supports_sse2()) { 4426 StubRoutines::_dexp = generate_libmExp(); 4427 StubRoutines::_dlog = generate_libmLog(); 4428 } 4429 } 4430 4431 void generate_all() { 4432 // Generates all stubs and initializes the entry points 4433 4434 // These entry points require SharedInfo::stack0 to be set up in 4435 // non-core builds and need to be relocatable, so they each 4436 // fabricate a RuntimeStub internally. 4437 StubRoutines::_throw_AbstractMethodError_entry = 4438 generate_throw_exception("AbstractMethodError throw_exception", 4439 CAST_FROM_FN_PTR(address, 4440 SharedRuntime:: 4441 throw_AbstractMethodError)); 4442 4443 StubRoutines::_throw_IncompatibleClassChangeError_entry = 4444 generate_throw_exception("IncompatibleClassChangeError throw_exception", 4445 CAST_FROM_FN_PTR(address, 4446 SharedRuntime:: 4447 throw_IncompatibleClassChangeError)); | 2970 2971 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit; 2972 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit; 2973 } 2974 2975 void generate_math_stubs() { 2976 { 2977 StubCodeMark mark(this, "StubRoutines", "log10"); 2978 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 2979 2980 __ subq(rsp, 8); 2981 __ movdbl(Address(rsp, 0), xmm0); 2982 __ fld_d(Address(rsp, 0)); 2983 __ flog10(); 2984 __ fstp_d(Address(rsp, 0)); 2985 __ movdbl(xmm0, Address(rsp, 0)); 2986 __ addq(rsp, 8); 2987 __ ret(0); 2988 } 2989 { 2990 StubCodeMark mark(this, "StubRoutines", "tan"); 2991 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 2992 2993 __ subq(rsp, 8); 2994 __ movdbl(Address(rsp, 0), xmm0); 2995 __ fld_d(Address(rsp, 0)); 2996 __ trigfunc('t'); 2997 __ fstp_d(Address(rsp, 0)); 2998 __ movdbl(xmm0, Address(rsp, 0)); 2999 __ addq(rsp, 8); 3000 __ ret(0); 3001 } 3002 { 3003 StubCodeMark mark(this, "StubRoutines", "pow"); 3004 StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc(); 3005 3006 __ subq(rsp, 8); 3007 __ movdbl(Address(rsp, 0), xmm1); 3008 __ fld_d(Address(rsp, 0)); 3009 __ movdbl(Address(rsp, 0), xmm0); 4192 __ subptr(rsp, 4 * wordSize); 4193 __ movdqu(Address(rsp, 0), xmm6); 4194 __ movdqu(Address(rsp, 2 * wordSize), xmm7); 4195 #endif 4196 __ fast_log(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2); 4197 4198 #ifdef _WIN64 4199 // restore xmm regs belonging to calling function 4200 __ movdqu(xmm6, Address(rsp, 0)); 4201 __ movdqu(xmm7, Address(rsp, 2 * wordSize)); 4202 __ addptr(rsp, 4 * wordSize); 4203 #endif 4204 4205 __ leave(); // required for proper stackwalking of RuntimeStub frame 4206 __ ret(0); 4207 4208 return start; 4209 4210 } 4211 4212 address generate_libmSin() { 4213 address start = __ pc(); 4214 4215 const XMMRegister x0 = xmm0; 4216 const XMMRegister x1 = xmm1; 4217 const XMMRegister x2 = xmm2; 4218 const XMMRegister x3 = xmm3; 4219 4220 const XMMRegister x4 = xmm4; 4221 const XMMRegister x5 = xmm5; 4222 const XMMRegister x6 = xmm6; 4223 const XMMRegister x7 = xmm7; 4224 4225 const Register tmp1 = r8; 4226 const Register tmp2 = r9; 4227 const Register tmp3 = r10; 4228 const Register tmp4 = r11; 4229 4230 BLOCK_COMMENT("Entry:"); 4231 __ enter(); // required for proper stackwalking of RuntimeStub frame 4232 4233 #ifdef _WIN64 4234 // save the xmm registers which must be preserved 6-7 4235 __ subptr(rsp, 4 * wordSize); 4236 __ movdqu(Address(rsp, 0), xmm6); 4237 __ movdqu(Address(rsp, 2 * wordSize), xmm7); 4238 #endif 4239 __ fast_sin(x0, x1, x2, x3, x4, x5, x6, x7, rax, rbx, rcx, rdx, tmp1, tmp2, tmp3, tmp4); 4240 4241 #ifdef _WIN64 4242 // restore xmm regs belonging to calling function 4243 __ movdqu(xmm6, Address(rsp, 0)); 4244 __ movdqu(xmm7, Address(rsp, 2 * wordSize)); 4245 __ addptr(rsp, 4 * wordSize); 4246 #endif 4247 4248 __ leave(); // required for proper stackwalking of RuntimeStub frame 4249 __ ret(0); 4250 4251 return start; 4252 4253 } 4254 4255 address generate_libmCos() { 4256 address start = __ pc(); 4257 4258 const XMMRegister x0 = xmm0; 4259 const XMMRegister x1 = xmm1; 4260 const XMMRegister x2 = xmm2; 4261 const XMMRegister x3 = xmm3; 4262 4263 const XMMRegister x4 = xmm4; 4264 const XMMRegister x5 = xmm5; 4265 const XMMRegister x6 = xmm6; 4266 const XMMRegister x7 = xmm7; 4267 4268 const Register tmp1 = r8; 4269 const Register tmp2 = r9; 4270 const Register tmp3 = r10; 4271 const Register tmp4 = r11; 4272 4273 BLOCK_COMMENT("Entry:"); 4274 __ enter(); // required for proper stackwalking of RuntimeStub frame 4275 4276 #ifdef _WIN64 4277 // save the xmm registers which must be preserved 6-7 4278 __ subptr(rsp, 4 * wordSize); 4279 __ movdqu(Address(rsp, 0), xmm6); 4280 __ movdqu(Address(rsp, 2 * wordSize), xmm7); 4281 #endif 4282 __ fast_cos(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4); 4283 4284 #ifdef _WIN64 4285 // restore xmm regs belonging to calling function 4286 __ movdqu(xmm6, Address(rsp, 0)); 4287 __ movdqu(xmm7, Address(rsp, 2 * wordSize)); 4288 __ addptr(rsp, 4 * wordSize); 4289 #endif 4290 4291 __ leave(); // required for proper stackwalking of RuntimeStub frame 4292 __ ret(0); 4293 4294 return start; 4295 4296 } 4297 4298 #undef __ 4299 #define __ masm-> 4300 4301 // Continuation point for throwing of implicit exceptions that are 4302 // not handled in the current activation. Fabricates an exception 4303 // oop and initiates normal exception dispatching in this 4304 // frame. Since we need to preserve callee-saved values (currently 4305 // only for C2, but done for C1 as well) we need a callee-saved oop 4306 // map and therefore have to make these stubs into RuntimeStubs 4307 // rather than BufferBlobs. If the compiler needs all registers to 4308 // be preserved between the fault point and the exception handler 4309 // then it must assume responsibility for that in 4310 // AbstractCompiler::continuation_for_implicit_null_exception or 4311 // continuation_for_implicit_division_by_zero_exception. All other 4312 // implicit exceptions (e.g., NullPointerException or 4313 // AbstractMethodError on entry) are either at call sites or 4314 // otherwise assume that stack unwinding will be initiated, so 4315 // caller saved registers were assumed volatile in the compiler. 4316 address generate_throw_exception(const char* name, 4467 StubRoutines::_throw_StackOverflowError_entry = 4468 generate_throw_exception("StackOverflowError throw_exception", 4469 CAST_FROM_FN_PTR(address, 4470 SharedRuntime:: 4471 throw_StackOverflowError)); 4472 if (UseCRC32Intrinsics) { 4473 // set table address before stub generation which use it 4474 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 4475 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 4476 } 4477 4478 if (UseCRC32CIntrinsics) { 4479 bool supports_clmul = VM_Version::supports_clmul(); 4480 StubRoutines::x86::generate_CRC32C_table(supports_clmul); 4481 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; 4482 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); 4483 } 4484 if (VM_Version::supports_sse2()) { 4485 StubRoutines::_dexp = generate_libmExp(); 4486 StubRoutines::_dlog = generate_libmLog(); 4487 if (UseLibmSinIntrinsic) { 4488 StubRoutines::_dsin = generate_libmSin(); 4489 } 4490 if (UseLibmCosIntrinsic) { 4491 StubRoutines::_dcos = generate_libmCos(); 4492 } 4493 } 4494 } 4495 4496 void generate_all() { 4497 // Generates all stubs and initializes the entry points 4498 4499 // These entry points require SharedInfo::stack0 to be set up in 4500 // non-core builds and need to be relocatable, so they each 4501 // fabricate a RuntimeStub internally. 4502 StubRoutines::_throw_AbstractMethodError_entry = 4503 generate_throw_exception("AbstractMethodError throw_exception", 4504 CAST_FROM_FN_PTR(address, 4505 SharedRuntime:: 4506 throw_AbstractMethodError)); 4507 4508 StubRoutines::_throw_IncompatibleClassChangeError_entry = 4509 generate_throw_exception("IncompatibleClassChangeError throw_exception", 4510 CAST_FROM_FN_PTR(address, 4511 SharedRuntime:: 4512 throw_IncompatibleClassChangeError)); |