5248 __ enter(); // required for proper stackwalking of RuntimeStub frame 5249 5250 setup_arg_regs(4); // out => rdi, in => rsi, offset => rdx 5251 // len => rcx, k => r8 5252 // r9 and r10 may be used to save non-volatile registers 5253 #ifdef _WIN64 5254 // last argument is on stack on Win64 5255 __ movl(k, Address(rsp, 6 * wordSize)); 5256 #endif 5257 __ movptr(r11, rdx); // move offset in rdx to offset(r11) 5258 __ mul_add(out, in, offset, len, k, tmp1, tmp2, tmp3, tmp4, tmp5, rdx, rax); 5259 5260 restore_arg_regs(); 5261 5262 __ leave(); // required for proper stackwalking of RuntimeStub frame 5263 __ ret(0); 5264 5265 return start; 5266 } 5267 5268 address generate_libmExp() { 5269 StubCodeMark mark(this, "StubRoutines", "libmExp"); 5270 5271 address start = __ pc(); 5272 5273 const XMMRegister x0 = xmm0; 5274 const XMMRegister x1 = xmm1; 5275 const XMMRegister x2 = xmm2; 5276 const XMMRegister x3 = xmm3; 5277 5278 const XMMRegister x4 = xmm4; 5279 const XMMRegister x5 = xmm5; 5280 const XMMRegister x6 = xmm6; 5281 const XMMRegister x7 = xmm7; 5282 5283 const Register tmp = r11; 5284 5285 BLOCK_COMMENT("Entry:"); 5286 __ enter(); // required for proper stackwalking of RuntimeStub frame 5287 5718 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) { 5719 StubRoutines::_dexp = generate_libmExp(); 5720 } 5721 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) { 5722 StubRoutines::_dlog = generate_libmLog(); 5723 } 5724 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) { 5725 StubRoutines::_dlog10 = generate_libmLog10(); 5726 } 5727 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) { 5728 StubRoutines::_dpow = generate_libmPow(); 5729 } 5730 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) { 5731 StubRoutines::_dsin = generate_libmSin(); 5732 } 5733 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) { 5734 StubRoutines::_dcos = generate_libmCos(); 5735 } 5736 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) { 5737 StubRoutines::_dtan = generate_libmTan(); 5738 } 5739 } 5740 } 5741 5742 void generate_all() { 5743 // Generates all stubs and initializes the entry points 5744 5745 // These entry points require SharedInfo::stack0 to be set up in 5746 // non-core builds and need to be relocatable, so they each 5747 // fabricate a RuntimeStub internally. 5748 StubRoutines::_throw_AbstractMethodError_entry = 5749 generate_throw_exception("AbstractMethodError throw_exception", 5750 CAST_FROM_FN_PTR(address, 5751 SharedRuntime:: 5752 throw_AbstractMethodError)); 5753 5754 StubRoutines::_throw_IncompatibleClassChangeError_entry = 5755 generate_throw_exception("IncompatibleClassChangeError throw_exception", 5756 CAST_FROM_FN_PTR(address, 5757 SharedRuntime:: | 5248 __ enter(); // required for proper stackwalking of RuntimeStub frame 5249 5250 setup_arg_regs(4); // out => rdi, in => rsi, offset => rdx 5251 // len => rcx, k => r8 5252 // r9 and r10 may be used to save non-volatile registers 5253 #ifdef _WIN64 5254 // last argument is on stack on Win64 5255 __ movl(k, Address(rsp, 6 * wordSize)); 5256 #endif 5257 __ movptr(r11, rdx); // move offset in rdx to offset(r11) 5258 __ mul_add(out, in, offset, len, k, tmp1, tmp2, tmp3, tmp4, tmp5, rdx, rax); 5259 5260 restore_arg_regs(); 5261 5262 __ leave(); // required for proper stackwalking of RuntimeStub frame 5263 __ ret(0); 5264 5265 return start; 5266 } 5267 5268 address generate_setBit() { 5269 StubCodeMark mark(this, "StubRoutines", "setBit"); 5270 5271 return generate_bit(true); 5272 } 5273 5274 address generate_clrBit() { 5275 StubCodeMark mark(this, "StubRoutines", "clrBit"); 5276 5277 return generate_bit(false); 5278 } 5279 5280 /** 5281 * Arguments: 5282 * 5283 * Inputs: 5284 * c_rarg0 - byte[] bits 5285 * c_rarg1 - int index 5286 */ 5287 address generate_bit(bool set) { 5288 address start = __ pc(); 5289 5290 __ enter(); // required for proper stackwalking of RuntimeStub frame 5291 5292 const Register bits = c_rarg0; 5293 const Register index = c_rarg1; 5294 5295 Label L_return; 5296 5297 __ movl(rbx, index); 5298 __ movptr(rdx, bits); 5299 5300 __ movl(rcx, rbx); 5301 __ shrl(rbx, 3); // hi 5302 __ andl(rcx, 0x7); // lo 5303 5304 __ null_check(rdx, arrayOopDesc::length_offset_in_bytes()); 5305 __ cmpl(rbx, Address(rdx, arrayOopDesc::length_offset_in_bytes())); 5306 __ jccb(Assembler::aboveEqual, L_return); // TODO throw exception? 5307 5308 __ lock(); 5309 if (set) 5310 __ btsl(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rcx); 5311 else 5312 __ btrl(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rcx); 5313 5314 __ bind(L_return); 5315 __ leave(); // required for proper stackwalking of RuntimeStub frame 5316 __ ret(0); 5317 5318 return start; 5319 } 5320 5321 address generate_libmExp() { 5322 StubCodeMark mark(this, "StubRoutines", "libmExp"); 5323 5324 address start = __ pc(); 5325 5326 const XMMRegister x0 = xmm0; 5327 const XMMRegister x1 = xmm1; 5328 const XMMRegister x2 = xmm2; 5329 const XMMRegister x3 = xmm3; 5330 5331 const XMMRegister x4 = xmm4; 5332 const XMMRegister x5 = xmm5; 5333 const XMMRegister x6 = xmm6; 5334 const XMMRegister x7 = xmm7; 5335 5336 const Register tmp = r11; 5337 5338 BLOCK_COMMENT("Entry:"); 5339 __ enter(); // required for proper stackwalking of RuntimeStub frame 5340 5771 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) { 5772 StubRoutines::_dexp = generate_libmExp(); 5773 } 5774 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) { 5775 StubRoutines::_dlog = generate_libmLog(); 5776 } 5777 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) { 5778 StubRoutines::_dlog10 = generate_libmLog10(); 5779 } 5780 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) { 5781 StubRoutines::_dpow = generate_libmPow(); 5782 } 5783 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) { 5784 StubRoutines::_dsin = generate_libmSin(); 5785 } 5786 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) { 5787 StubRoutines::_dcos = generate_libmCos(); 5788 } 5789 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) { 5790 StubRoutines::_dtan = generate_libmTan(); 5791 } 5792 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_setBit)) { 5793 StubRoutines::_setBit = generate_setBit(); 5794 } 5795 if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_clrBit)) { 5796 StubRoutines::_clrBit = generate_clrBit(); 5797 } 5798 } 5799 } 5800 5801 void generate_all() { 5802 // Generates all stubs and initializes the entry points 5803 5804 // These entry points require SharedInfo::stack0 to be set up in 5805 // non-core builds and need to be relocatable, so they each 5806 // fabricate a RuntimeStub internally. 5807 StubRoutines::_throw_AbstractMethodError_entry = 5808 generate_throw_exception("AbstractMethodError throw_exception", 5809 CAST_FROM_FN_PTR(address, 5810 SharedRuntime:: 5811 throw_AbstractMethodError)); 5812 5813 StubRoutines::_throw_IncompatibleClassChangeError_entry = 5814 generate_throw_exception("IncompatibleClassChangeError throw_exception", 5815 CAST_FROM_FN_PTR(address, 5816 SharedRuntime:: |