1、名字解釋:
ABI,application binary interface (ABI),應用程序二進制接口。
2、編譯版本問題:
GCC 4.0 為分界線
4.0版本以下,由于采用OABI接口,其對浮點的支持不太好
4.0版本以上,采用了新的EABI接口,其對軟浮點和硬浮點的支持都比較好。
考慮在4.0版本以下時,其支持的ARM內核大多數沒有硬浮點,所以可以分析資料比較少,
現在重點關注4.0版本以上。以下所述都是針對4.0版本以上的。
3、編譯器相關的參數:
-mfloat-abi=soft 使用這個參數時,其將調用軟浮點庫(softfloat lib)來支持對浮點的運算,GCC編譯器已經有這個庫了,一般在libgcc里面。這時根本不會使用任何浮點指令,而是采用常用的指令來模擬浮點運算。 但使用的ARM芯片不支持硬浮點時,可以考慮使用這個參數。在使用這個參數時,連接時一般會出現下面的提示:
undefined reference to `__aeabi_fdiv'
或者類似的提示,主要因為一般情況下連接器沒有去主動尋找軟浮點庫,這時使用將libgcc庫加入即可。
-mfloat-abi=softfp
-mfloat-abi=hard
這兩個參數都用來產生硬浮點指令,至于產生哪里類型的硬浮點指令,需要由-mfpu=xxx參數來指令。這兩個參數不同的地方是:
-mfloat-abi=softfp生成的代碼采用兼容軟浮點調用接口(即使用-mfloat-abi=soft時的調用接口),這樣帶來的好處是:兼 容性和靈活性。庫可以采用-mfloat-abi=soft編譯,而關鍵的應用程序可以采用-mfloat-abi=softfp來編譯。特別是在庫由第 三方發布的情況下。
-mfloat-abi=hard生成的代碼采用硬浮點(FPU)調用接口。這樣要求所有庫和應用程序必須采用這同一個參數來編譯,否則連接時會出現接口不兼容錯誤。
-mfpu=vfp
-mfpu=fpa
...
前面已經講述了,-mfpu參數就是用來指定要產生哪種硬浮點指令。常見的有vfp,fpa等。
4、編譯器使用時要注意的地方:
a.確認編譯器默認是使用哪種參數來處理浮點操作的。寫一個簡單的浮點數程序:
#include
int main(void)
{
double d1 = 10.3;
double d2 = 2.0;
double dret = d1/d2;
dret++;
printf("result :%f",dret);
return 0;
}
然后使用
arm-linux-gcc -c main.c -o main.o
再使用
arm-linux-objdump -d main.o
然后觀察產生的指令,從而確定默認使用的是軟浮點還是硬浮點。(確認的過程,看個人。晃一眼,里面如果有不熟悉指令,那可能就是硬浮點指令了)
b.確認編譯器所帶的庫使用哪種參數來編譯的。
c.確認所使用的芯片是否支持硬浮點,如果支持,是哪種類型的浮點指令。如果1,2與使用的芯片相沖突,這時就要考慮另尋編譯器了。
這三點確認以后,我們在寫自己的應用程序時,就會知道該怎樣使用這些參數了。
5、Linux相關問題:
這里涉及兩個問題:
問題1:使用的ARM芯片不支持硬浮點
在配置ARM Linux內核時,應該都會看到這樣的配置:
menu "Floating point emulation"
comment "At least one emulation must be selected"
config FPE_NWFPE
...
這個是用來配置在內核里面模擬浮點處理器。
這個配置有什么作用呢?估計很少有人能夠知道。其實它是這樣的:
當使用的ARM芯片不支持硬浮點,而又采用了-mfpu=fpa -mfloat-abi=softfp/hard來編譯應用程序。現在應該知道,采用這樣的參數是要參數fpa硬浮點指令。但是使用的ARM芯片不支持硬 浮點,這時這個配置就其作用了。因為使用了fpa硬浮點指令,但使用的ARM芯片不支持硬浮點,這樣當程序運行到fpa硬浮點指令,會出現指令異常,便會 陷入到內核里,這時這個模擬浮點處理器就來模擬這些浮點指令。現在應該清楚了,其作用了吧。但是現在有了更好的辦法,前面已經講過了,采用 -mfloat-abi=soft參數來編譯應用程序,這樣效率會快得多。想想從用戶態切換到內核態,以及由此產生的cache和TLB表的損失。所以可 以考慮將這個配置拋棄了。
|