Changeset 94692 in vbox
- Timestamp:
- Apr 22, 2022 9:38:41 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 151065
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r94683 r94692 5701 5701 5702 5702 5703 IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r32,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 5703 /** 5704 * Worker for fcom, fucom, and friends. 5705 */ 5706 static uint16_t iemAImpl_fcom_r80_by_r80_worker(PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, 5707 uint16_t fFcw, uint16_t fFsw, bool fIeOnAllNaNs) 5708 { 5709 /* 5710 * Unpack the values. 5711 */ 5712 bool const fSign1 = pr80Val1->s.fSign; 5713 int32_t iExponent1 = pr80Val1->s.uExponent; 5714 uint64_t uMantissa1 = pr80Val1->s.uMantissa; 5715 5716 bool const fSign2 = pr80Val2->s.fSign; 5717 int32_t iExponent2 = pr80Val2->s.uExponent; 5718 uint64_t uMantissa2 = pr80Val2->s.uMantissa; 5719 5720 /* 5721 * Check for invalid inputs. 5722 */ 5723 if ( RTFLOAT80U_IS_387_INVALID_EX(uMantissa1, iExponent1) 5724 || RTFLOAT80U_IS_387_INVALID_EX(uMantissa2, iExponent2)) 5725 { 5726 if (!(fFcw & X86_FCW_IM)) 5727 fFsw |= X86_FSW_ES | X86_FSW_B; 5728 return fFsw | X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 | X86_FSW_IE; 5729 } 5730 5731 /* 5732 * Check for NaNs and indefinites, they are all unordered and trumps #DE. 5733 */ 5734 if ( RTFLOAT80U_IS_INDEFINITE_OR_QUIET_OR_SIGNALLING_NAN_EX(uMantissa1, iExponent1) 5735 || RTFLOAT80U_IS_INDEFINITE_OR_QUIET_OR_SIGNALLING_NAN_EX(uMantissa2, iExponent2)) 5736 { 5737 if ( fIeOnAllNaNs 5738 || RTFLOAT80U_IS_SIGNALLING_NAN_EX(uMantissa1, iExponent1) 5739 || RTFLOAT80U_IS_SIGNALLING_NAN_EX(uMantissa2, iExponent2)) 5740 { 5741 fFsw |= X86_FSW_IE; 5742 if (!(fFcw & X86_FCW_IM)) 5743 fFsw |= X86_FSW_ES | X86_FSW_B; 5744 } 5745 return fFsw | X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3; 5746 } 5747 5748 /* 5749 * Normalize the values. 5750 */ 5751 if (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL_EX(uMantissa1, iExponent1)) 5752 { 5753 if (RTFLOAT80U_IS_PSEUDO_DENORMAL_EX(uMantissa1, iExponent1)) 5754 iExponent1 = 1; 5755 else 5756 { 5757 iExponent1 = 64 - ASMBitLastSetU64(uMantissa1); 5758 uMantissa1 <<= iExponent1; 5759 iExponent1 = 1 - iExponent1; 5760 } 5761 fFsw |= X86_FSW_DE; 5762 if (!(fFcw & X86_FCW_DM)) 5763 fFsw |= X86_FSW_ES | X86_FSW_B; 5764 } 5765 5766 if (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL_EX(uMantissa2, iExponent2)) 5767 { 5768 if (RTFLOAT80U_IS_PSEUDO_DENORMAL_EX(uMantissa2, iExponent2)) 5769 iExponent2 = 1; 5770 else 5771 { 5772 iExponent2 = 64 - ASMBitLastSetU64(uMantissa2); 5773 uMantissa2 <<= iExponent2; 5774 iExponent2 = 1 - iExponent2; 5775 } 5776 fFsw |= X86_FSW_DE; 5777 if (!(fFcw & X86_FCW_DM)) 5778 fFsw |= X86_FSW_ES | X86_FSW_B; 5779 } 5780 5781 /* 5782 * Test if equal (val1 == val2): 5783 */ 5784 if ( uMantissa1 == uMantissa2 5785 && iExponent1 == iExponent2 5786 && ( fSign1 == fSign2 5787 || (uMantissa1 == 0 && iExponent1 == 0) /* ignore sign for zero */ ) ) 5788 fFsw |= X86_FSW_C3; 5789 /* 5790 * Test if less than (val1 < val2): 5791 */ 5792 else if (fSign1 && !fSign2) 5793 fFsw |= X86_FSW_C0; 5794 else if (fSign1 == fSign2) 5795 { 5796 /* Zeros are problematic, however at the most one can be zero here. */ 5797 if (RTFLOAT80U_IS_ZERO_EX(uMantissa1, iExponent1)) 5798 return !fSign1 ? fFsw | X86_FSW_C0 : fFsw; 5799 if (RTFLOAT80U_IS_ZERO_EX(uMantissa2, iExponent2)) 5800 return fSign1 ? fFsw | X86_FSW_C0 : fFsw; 5801 5802 if ( fSign1 5803 ^ ( iExponent1 < iExponent2 5804 || ( iExponent1 == iExponent2 5805 && uMantissa1 < uMantissa2 ) ) ) 5806 fFsw |= X86_FSW_C0; 5807 } 5808 /* else: No flags set if greater. */ 5809 5810 return fFsw; 5811 } 5812 5813 5814 IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5815 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5816 { 5817 *pfFsw = iemAImpl_fcom_r80_by_r80_worker(pr80Val1, pr80Val2, pFpuState->FCW, 6 << X86_FSW_TOP_SHIFT, true /*fIeOnAllNaNs*/); 5818 } 5819 5820 5821 5822 5823 IEM_DECL_IMPL_DEF(void, iemAImpl_fucom_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5824 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5825 { 5826 *pfFsw = iemAImpl_fcom_r80_by_r80_worker(pr80Val1, pr80Val2, pFpuState->FCW, 6 << X86_FSW_TOP_SHIFT, false /*fIeOnAllNaNs*/); 5827 } 5828 5829 5830 IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r64,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5831 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2)) 5832 { 5833 RTFLOAT80U r80Val2; 5834 uint16_t fFsw = iemAImplConvertR64ToR80(pr64Val2, &r80Val2); 5835 Assert(!fFsw || fFsw == X86_FSW_DE); 5836 *pfFsw = iemAImpl_fcom_r80_by_r80_worker(pr80Val1, &r80Val2, pFpuState->FCW, 7 << X86_FSW_TOP_SHIFT, true /*fIeOnAllNaNs*/); 5837 if (fFsw != 0 && !(*pfFsw & X86_FSW_IE)) 5838 { 5839 if (!(pFpuState->FCW & X86_FCW_DM)) 5840 fFsw |= X86_FSW_ES | X86_FSW_B; 5841 *pfFsw |= fFsw; 5842 } 5843 } 5844 5845 5846 IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r32,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5704 5847 PCRTFLOAT80U pr80Val1, PCRTFLOAT32U pr32Val2)) 5705 5848 { 5706 RT_NOREF(pFpuState, pFSW, pr80Val1, pr32Val2); 5707 AssertReleaseFailed(); 5708 } 5709 5710 5711 IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r64,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 5712 PCRTFLOAT80U pr80Val1, PCRTFLOAT64U pr64Val2)) 5713 { 5714 RT_NOREF(pFpuState, pFSW, pr80Val1, pr64Val2); 5715 AssertReleaseFailed(); 5716 } 5717 5718 5719 IEM_DECL_IMPL_DEF(void, iemAImpl_fcom_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 5720 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5721 { 5722 RT_NOREF(pFpuState, pFSW, pr80Val1, pr80Val2); 5723 AssertReleaseFailed(); 5724 } 5725 5726 5727 IEM_DECL_IMPL_DEF(uint32_t, iemAImpl_fcomi_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 5849 RTFLOAT80U r80Val2; 5850 uint16_t fFsw = iemAImplConvertR32ToR80(pr32Val2, &r80Val2); 5851 Assert(!fFsw || fFsw == X86_FSW_DE); 5852 *pfFsw = iemAImpl_fcom_r80_by_r80_worker(pr80Val1, &r80Val2, pFpuState->FCW, 7 << X86_FSW_TOP_SHIFT, true /*fIeOnAllNaNs*/); 5853 if (fFsw != 0 && !(*pfFsw & X86_FSW_IE)) 5854 { 5855 if (!(pFpuState->FCW & X86_FCW_DM)) 5856 fFsw |= X86_FSW_ES | X86_FSW_B; 5857 *pfFsw |= fFsw; 5858 } 5859 } 5860 5861 5862 IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i32,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5863 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2)) 5864 { 5865 RTFLOAT80U r80Val2; 5866 iemAImpl_fcom_r80_by_r80(pFpuState, pfFsw, pr80Val1, iemAImplConvertI32ToR80(*pi32Val2, &r80Val2)); 5867 *pfFsw = (*pfFsw & ~X86_FSW_TOP_MASK) | (7 << X86_FSW_TOP_SHIFT); 5868 } 5869 5870 5871 IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i16,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5872 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2)) 5873 { 5874 RTFLOAT80U r80Val2; 5875 iemAImpl_fcom_r80_by_r80(pFpuState, pfFsw, pr80Val1, iemAImplConvertI16ToR80(*pi16Val2, &r80Val2)); 5876 *pfFsw = (*pfFsw & ~X86_FSW_TOP_MASK) | (7 << X86_FSW_TOP_SHIFT); 5877 } 5878 5879 5880 /** 5881 * Worker for fcomi & fucomi. 5882 */ 5883 static uint32_t iemAImpl_fcomi_r80_by_r80_worker(PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2, 5884 uint16_t fFcw, uint16_t fFswIn, bool fIeOnAllNaNs, uint16_t *pfFsw) 5885 { 5886 uint16_t fFsw = iemAImpl_fcom_r80_by_r80_worker(pr80Val1, pr80Val2, fFcw, 6 << X86_FSW_TOP_SHIFT, fIeOnAllNaNs); 5887 uint32_t fEflags = ((fFsw & X86_FSW_C3) >> (X86_FSW_C3_BIT - X86_EFL_ZF_BIT)) 5888 | ((fFsw & X86_FSW_C2) >> (X86_FSW_C2_BIT - X86_EFL_PF_BIT)) 5889 | ((fFsw & X86_FSW_C0) >> (X86_FSW_C0_BIT - X86_EFL_CF_BIT)); 5890 5891 /* Note! C1 is not cleared as per docs! Everything is preserved. */ 5892 *pfFsw = (fFsw & ~X86_FSW_C_MASK) | (fFswIn & X86_FSW_C_MASK); 5893 return fEflags | X86_EFL_IF | X86_EFL_RA1_MASK; 5894 } 5895 5896 5897 IEM_DECL_IMPL_DEF(uint32_t, iemAImpl_fcomi_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5728 5898 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5729 5899 { 5730 RT_NOREF(pFpuState, pFSW, pr80Val1, pr80Val2); 5731 AssertReleaseFailed(); 5732 return 0; 5733 } 5734 5735 5736 IEM_DECL_IMPL_DEF(void, iemAImpl_fucom_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pFSW, 5737 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5738 { 5739 RT_NOREF(pFpuState, pFSW, pr80Val1, pr80Val2); 5740 AssertReleaseFailed(); 5741 } 5742 5743 5744 IEM_DECL_IMPL_DEF(uint32_t, iemAImpl_fucomi_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, 5900 return iemAImpl_fcomi_r80_by_r80_worker(pr80Val1, pr80Val2, pFpuState->FCW, pFpuState->FSW, true /*fIeOnAllNaNs*/, pfFsw); 5901 } 5902 5903 5904 IEM_DECL_IMPL_DEF(uint32_t, iemAImpl_fucomi_r80_by_r80,(PCX86FXSTATE pFpuState, uint16_t *pfFsw, 5745 5905 PCRTFLOAT80U pr80Val1, PCRTFLOAT80U pr80Val2)) 5746 5906 { 5747 RT_NOREF(pFpuState, pu16Fsw, pr80Val1, pr80Val2); 5748 AssertReleaseFailed(); 5749 return 0; 5750 } 5751 5752 5753 IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i16,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, 5754 PCRTFLOAT80U pr80Val1, int16_t const *pi16Val2)) 5755 { 5756 RT_NOREF(pFpuState, pu16Fsw, pr80Val1, pi16Val2); 5757 AssertReleaseFailed(); 5758 } 5759 5760 5761 IEM_DECL_IMPL_DEF(void, iemAImpl_ficom_r80_by_i32,(PCX86FXSTATE pFpuState, uint16_t *pu16Fsw, 5762 PCRTFLOAT80U pr80Val1, int32_t const *pi32Val2)) 5763 { 5764 RT_NOREF(pFpuState, pu16Fsw, pr80Val1, pi32Val2); 5765 AssertReleaseFailed(); 5907 return iemAImpl_fcomi_r80_by_r80_worker(pr80Val1, pr80Val2, pFpuState->FCW, pFpuState->FSW, false /*fIeOnAllNaNs*/, pfFsw); 5766 5908 } 5767 5909
Note:
See TracChangeset
for help on using the changeset viewer.