2012-12-28 70 views
1

我想編譯libsoxr(它來自libsox庫由Audacity團隊)庫。我可以編譯osx 32,osx 64和win32。他們使用內聯asm,而Windows x64平臺不支持內聯asm。有問題的代碼塊是這樣的:libsoxr在Windows x64平臺,內聯asm不編譯

#if HAVE_FENV_H 
    #include <fenv.h> 
#elif defined _MSC_VER 
    #define FE_INVALID 1 
    #define FE_DIVBYZERO 4 
    #define FE_OVERFLOW 8 
    #define FE_UNDERFLOW 16 
    #define FE_INEXACT 32 
    #define FE_ALL_EXCEPT (FE_INEXACT|FE_DIVBYZERO|FE_UNDERFLOW|FE_OVERFLOW|FE_INVALID) 
    static __inline int fetestexcept(int excepts) 
    { 
    short status_word; 
    __asm fnstsw status_word 
    return status_word & excepts & FE_ALL_EXCEPT; 
    } 

    static __inline int feclearexcept(int excepts) 
    { 
    int16_t status[14]; 
    __asm fnstenv status 
    status[2] &= ~(excepts & FE_ALL_EXCEPT); 
    __asm fldenv status 
    return 0; 
    } 
#endif 

我不知道是什麼fnstenvfldenv做。可能有人指導我與x64兼容嗎?

+0

這些說明正在處理x87狀態。 Windows x64通常不使用x87浮點,而是使用SSE浮點指令。 –

+0

我正在使用Visual C++ express edition 2012. –

回答

2

假設您正在使用Microsoft編譯器進行編譯,那麼您可以使用RTL函數而不是內聯彙編。

要測試特定的浮點狀態標誌,請撥打_statusfp。要清除浮點狀態標誌,請致電_clearfp

要使用_statusfp,您需要將原始8087標誌翻譯爲_statusfp使用的抽象標誌。

更新

在問題中的代碼是fenv.h一小部分,其是C99的一部分的實施方案。 MS編譯器需要它,因爲它只實現C89。在我看來,使用真正的C99編譯器會更好。這將與執行fenv.h

+0

謝謝您的回答。我看了'fnstenv',它需要28個字節的信息,但'_statusfp'只返回'int'(4個字節)。在代碼中,他們僅使用第二個16位按位操作。你認爲我需要嘗試_statusfp2嗎?因爲它需要unsigned int指針。我無法找到有關需要多少字節的信息。 –

+0

嗯,'feclearexcept'允許您清除選定的例外,但'_clearfp'清除所有例外。我不確定MSVC RTL支持只清除一些異常。但只有清楚一些纔會是很奇怪的。我打賭所有打電話給'feclearexcept'的人都清楚了。 –

+0

現在我明白了它是什麼。我可以嘗試'_clearfp'並查看結果。由於性能的原因,他們可能僅僅排在第二位16位。你怎麼看待'fnstsw'?這是我可以用於同一項工作的功能嗎? –

2

這兩個函數是C標準的一部分,所以我懷疑這是第一次有人希望他們用於MSVC - 請看看其他項目已經完成了什麼。如果沒有變成了和你想快速和簡單的解決方案,你應該能夠進一步限定

#elif指令定義_MSC_VER

指令,包裝此代碼編譯器(_M_X64)不使用這些內嵌彙編版本 - 默認(較慢)的代碼應該生效。

+0

問題中的兩個函數是C標準的一部分?真?標準在哪裏? –

+0

對不起,我不知道頁碼!快速谷歌揭示http://pubs.opengroup.org/onlinepubs/007904875/functions/fetestexcept.html其中有以下參考:ISO/IEC 9899:1999 AFAIK,這些功能也在較新的(2011)版本的兩個C&C++標準。 – Rob

+0

@Rob謝謝。其實我不必使用MS編譯器。我也可以使用gcc。這是一個dll項目。我在Windows上沒有gcc的經驗。我已經下載了MinGW64編譯器。 cmake和MinGW64存在問題。你有沒有使用64位Windows與GCC使用fenv.h? –