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 } |
3727 (framesize >> (LogBytesPerWord - LogBytesPerInt)), |
3728 (framesize >> (LogBytesPerWord - LogBytesPerInt)), |
3728 oop_maps, false); |
3729 oop_maps, false); |
3729 return stub->entry_point(); |
3730 return stub->entry_point(); |
3730 } |
3731 } |
3731 |
3732 |
|
3733 void create_control_words() { |
|
3734 // Round to nearest, 53-bit mode, exceptions masked |
|
3735 StubRoutines::_fpu_cntrl_wrd_std = 0x027F; |
|
3736 // Round to zero, 53-bit mode, exception mased |
|
3737 StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F; |
|
3738 // Round to nearest, 24-bit mode, exceptions masked |
|
3739 StubRoutines::_fpu_cntrl_wrd_24 = 0x007F; |
|
3740 // Round to nearest, 64-bit mode, exceptions masked |
|
3741 StubRoutines::_fpu_cntrl_wrd_64 = 0x037F; |
|
3742 // Round to nearest, 64-bit mode, exceptions masked |
|
3743 StubRoutines::_mxcsr_std = 0x1F80; |
|
3744 // Note: the following two constants are 80-bit values |
|
3745 // layout is critical for correct loading by FPU. |
|
3746 // Bias for strict fp multiply/divide |
|
3747 StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000 |
|
3748 StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000; |
|
3749 StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff; |
|
3750 // Un-Bias for strict fp multiply/divide |
|
3751 StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000 |
|
3752 StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000; |
|
3753 StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff; |
|
3754 } |
|
3755 |
3732 // Initialization |
3756 // Initialization |
3733 void generate_initial() { |
3757 void generate_initial() { |
3734 // Generates all stubs and initializes the entry points |
3758 // Generates all stubs and initializes the entry points |
3735 |
3759 |
3736 // This platform-specific stub is needed by generate_call_stub() |
3760 // This platform-specific settings are needed by generate_call_stub() |
3737 StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); |
3761 create_control_words(); |
3738 |
3762 |
3739 // entry points that exist in all platforms Note: This is code |
3763 // entry points that exist in all platforms Note: This is code |
3740 // that could be shared among different platforms - however the |
3764 // that could be shared among different platforms - however the |
3741 // benefit seems to be smaller than the disadvantage of having a |
3765 // benefit seems to be smaller than the disadvantage of having a |
3742 // much more complicated generator structure. See also comment in |
3766 // much more complicated generator structure. See also comment in |