277 { |
277 { |
278 Label skip_ldmx; |
278 Label skip_ldmx; |
279 __ stmxcsr(mxcsr_save); |
279 __ stmxcsr(mxcsr_save); |
280 __ movl(rax, mxcsr_save); |
280 __ movl(rax, mxcsr_save); |
281 __ andl(rax, MXCSR_MASK); // Only check control and mask bits |
281 __ andl(rax, MXCSR_MASK); // Only check control and mask bits |
282 ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std()); |
282 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); |
283 __ cmp32(rax, mxcsr_std); |
283 __ cmp32(rax, mxcsr_std); |
284 __ jcc(Assembler::equal, skip_ldmx); |
284 __ jcc(Assembler::equal, skip_ldmx); |
285 __ ldmxcsr(mxcsr_std); |
285 __ ldmxcsr(mxcsr_std); |
286 __ bind(skip_ldmx); |
286 __ bind(skip_ldmx); |
287 } |
287 } |
727 |
727 |
728 const Address mxcsr_save(rsp, 0); |
728 const Address mxcsr_save(rsp, 0); |
729 |
729 |
730 if (CheckJNICalls) { |
730 if (CheckJNICalls) { |
731 Label ok_ret; |
731 Label ok_ret; |
|
732 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); |
732 __ push(rax); |
733 __ push(rax); |
733 __ subptr(rsp, wordSize); // allocate a temp location |
734 __ subptr(rsp, wordSize); // allocate a temp location |
734 __ stmxcsr(mxcsr_save); |
735 __ stmxcsr(mxcsr_save); |
735 __ movl(rax, mxcsr_save); |
736 __ movl(rax, mxcsr_save); |
736 __ andl(rax, MXCSR_MASK); // Only check control and mask bits |
737 __ andl(rax, MXCSR_MASK); // Only check control and mask bits |
737 __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std())); |
738 __ cmp32(rax, mxcsr_std); |
738 __ jcc(Assembler::equal, ok_ret); |
739 __ jcc(Assembler::equal, ok_ret); |
739 |
740 |
740 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); |
741 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); |
741 |
742 |
742 __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); |
743 __ ldmxcsr(mxcsr_std); |
743 |
744 |
744 __ bind(ok_ret); |
745 __ bind(ok_ret); |
745 __ addptr(rsp, wordSize); |
746 __ addptr(rsp, wordSize); |
746 __ pop(rax); |
747 __ pop(rax); |
747 } |
748 } |
3765 (framesize >> (LogBytesPerWord - LogBytesPerInt)), |
3766 (framesize >> (LogBytesPerWord - LogBytesPerInt)), |
3766 oop_maps, false); |
3767 oop_maps, false); |
3767 return stub->entry_point(); |
3768 return stub->entry_point(); |
3768 } |
3769 } |
3769 |
3770 |
|
3771 void create_control_words() { |
|
3772 // Round to nearest, 53-bit mode, exceptions masked |
|
3773 StubRoutines::_fpu_cntrl_wrd_std = 0x027F; |
|
3774 // Round to zero, 53-bit mode, exception mased |
|
3775 StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F; |
|
3776 // Round to nearest, 24-bit mode, exceptions masked |
|
3777 StubRoutines::_fpu_cntrl_wrd_24 = 0x007F; |
|
3778 // Round to nearest, 64-bit mode, exceptions masked |
|
3779 StubRoutines::_fpu_cntrl_wrd_64 = 0x037F; |
|
3780 // Round to nearest, 64-bit mode, exceptions masked |
|
3781 StubRoutines::_mxcsr_std = 0x1F80; |
|
3782 // Note: the following two constants are 80-bit values |
|
3783 // layout is critical for correct loading by FPU. |
|
3784 // Bias for strict fp multiply/divide |
|
3785 StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000 |
|
3786 StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000; |
|
3787 StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff; |
|
3788 // Un-Bias for strict fp multiply/divide |
|
3789 StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000 |
|
3790 StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000; |
|
3791 StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff; |
|
3792 } |
|
3793 |
3770 // Initialization |
3794 // Initialization |
3771 void generate_initial() { |
3795 void generate_initial() { |
3772 // Generates all stubs and initializes the entry points |
3796 // Generates all stubs and initializes the entry points |
3773 |
3797 |
3774 // This platform-specific stub is needed by generate_call_stub() |
3798 // This platform-specific settings are needed by generate_call_stub() |
3775 StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); |
3799 create_control_words(); |
3776 |
3800 |
3777 // entry points that exist in all platforms Note: This is code |
3801 // entry points that exist in all platforms Note: This is code |
3778 // that could be shared among different platforms - however the |
3802 // that could be shared among different platforms - however the |
3779 // benefit seems to be smaller than the disadvantage of having a |
3803 // benefit seems to be smaller than the disadvantage of having a |
3780 // much more complicated generator structure. See also comment in |
3804 // much more complicated generator structure. See also comment in |