久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > ARM 浮點運算一
ARM 浮點運算一
時間:2016-12-14作者:華(hua)清遠見

很多時候我們要處理(li)的(de)數(shu)據,不僅僅是(shi)整數(shu)和字符(fu)串,還有浮點(dian)數(shu)即小數(shu)。在(zai)多媒(mei)體數(shu)據處理(li)方面(mian)表現的(de)更多。是(shi)不是(shi)所(suo)有的(de)CPU都(dou)支(zhi)持(chi),浮點(dian)運算呢?答案:不是(shi)。

我(wo)們(men)常常聽(ting)到贏浮(fu)點和(he)軟浮(fu)點,這(zhe)(zhe)些(xie)到底說的是什么呢?下面我(wo)們(men)就(jiu)來(lai)一探(tan)究竟吧。在這(zhe)(zhe)里我(wo)們(men)說的是ARM核浮(fu)點運算。

(1)硬浮點(hard-float)

編譯器(qi)將(jiang)代碼直(zhi)接編譯成硬件浮(fu)點協(xie)處(chu)理器(qi)(浮(fu)點運(yun)(yun)算單(dan)元FPU)能識(shi)別的(de)指令,這些指令在執行(xing)的(de)時候ARM核直(zhi)接把它轉(zhuan)給協(xie)處(chu)理器(qi)執行(xing)。FPU 通常(chang)有一套額外的(de)寄存(cun)器(qi)來完(wan)成浮(fu)點參(can)數傳(chuan)遞(di)和運(yun)(yun)算。使用實際的(de)硬件浮(fu)點運(yun)(yun)算單(dan)元(FPU)會帶來性能的(de)提升。

(2)軟浮(fu)點(dian)(soft-float)

編譯器(qi)把(ba)浮(fu)(fu)(fu)點(dian)運算轉(zhuan)成浮(fu)(fu)(fu)點(dian)運算的(de)函(han)數調(diao)(diao)用(yong)和庫函(han)數調(diao)(diao)用(yong),沒(mei)有(you)(you)FPU的(de)指(zhi)令調(diao)(diao)用(yong),也(ye)沒(mei)有(you)(you)浮(fu)(fu)(fu)點(dian)寄存(cun)器(qi)的(de)參(can)數傳(chuan)遞。浮(fu)(fu)(fu)點(dian)參(can)數的(de)傳(chuan)遞也(ye)是(shi)通過ARM寄存(cun)器(qi)或者堆棧完(wan)成。現在的(de)Linux系統默認編譯選擇使(shi)用(yong)hard-float,如果系統沒(mei)有(you)(you)任(ren)何浮(fu)(fu)(fu)點(dian)處理器(qi)單元,這就會產生非法指(zhi)令和異(yi)常。因(yin)而一般的(de)系統鏡像(xiang)都采(cai)用(yong)軟浮(fu)(fu)(fu)點(dian)以兼(jian)容沒(mei)有(you)(you)VFP的(de)處理器(qi)。

用(yong)一句話總結,軟浮(fu)點(dian)(dian)是通過浮(fu)點(dian)(dian)庫去(qu)實現浮(fu)點(dian)(dian)運(yun)算的,效率低;硬浮(fu)點(dian)(dian)是通過浮(fu)點(dian)(dian)運(yun)算單(dan)元(FPU)來完成的,效率高。

一、使(shi)用浮點(dian)(dian)庫實現浮點(dian)(dian)運算(soft-float)

例如:我想實現兩個(ge)浮點數相加(jia),代(dai)碼如下:

使(shi)用GNU ARM編譯(yi)器翻譯(yi)成的部分匯編代碼如下:

從圖中(zhong)我們可以(yi)知道,默認情況(kuang)下,編譯器使用的是軟浮點(dian),圖中(zhong)__aeabi_fadd這個函數是在浮點(dian)庫中(zhong)實(shi)現。如果想讓代(dai)碼能(neng)正(zheng)常(chang)的運行,還(huan)需要在連(lian)接(jie)的時候靜態連(lian)接(jie)一下浮點(dian)庫。

在這里我們以一(yi)個完成的(de)案(an)例來說(shuo)明一(yi)下,軟浮點庫(ku)的(de)使用方法。

start.S:
        .global _start
        #define USER_MODE 0x10
        _start:
        @設置CPU為user模式
        mov r0,#USER_MODE
        msr cpsr_c,r0
        @跳到main函數
        ldr sp,=0x34000
        bl main
        stop:
        b stop
        main.c:
        int main()
        {
                float f1,f2,f3;
                f1 = 1.24;
                f2 = 1.22;
                f3 = f1 + f2;
                return 0;
        }
        Makefile:
        LD=arm-none-eabi-ld
        OBJDUMP=arm-none-eabi-objdump
        RM=rm -rf
        CFLAG= -g -c
        ASFLAG=-g -c
        OBJ=start.o main.o
        LDFLAGS= -static -L\
        #指定浮點庫所在的路徑
        "C:\Program Files\yagarto\lib\gcc\arm-none-eabi\4.6.2" -lgcc
        #設置編譯模式
        %.o:%.S
        $(CC) $(ASFLAG) $< -o $@

        %.o:%.c
        $(CC) $(CFLAG) $< -o $@
        all:$(OBJ)
        $(LD) -Ttext=0x20000 $^ -o arm.elf $(LDFLAGS)
        $(OBJDUMP) -D arm.elf > arm.dis
        clean:
 &nbsp;      $(RM) *.o arm.dis arm.elf

使(shi)用硬(ying)件浮點實現(xian)浮點運算(suan)(hard-float)

使用硬件(jian)(jian)浮(fu)點(dian)的(de)時候,我(wo)們需(xu)要給編譯器(qi)傳(chuan)遞一(yi)些參數,讓編譯器(qi)編譯出硬件(jian)(jian)浮(fu)點(dian)單(dan)元(yuan)處理器(qi)能識別(bie)的(de)指令。

(1)-mfpu=name

參數-mfpu就是用來指(zhi)定(ding)要產生那種硬(ying)件浮點(dian)運算指(zhi)令,常(chang)用的右vfp和(he)neon等。

浮點協處理器指令:

ARM10 and ARM9:
        -mfpu=vfp(or vfpv1 or vfpv2)
        Cortex-A8:
        -mfpu=neon

(2) -mfloat-abi=value

-mfloat-abi=soft 使(shi)用(yong)(yong)(yong)(yong)這(zhe)個參(can)數(shu)時(shi),其將調用(yong)(yong)(yong)(yong)軟浮(fu)點(dian)庫(softfloat lib)來支持(chi)對浮(fu)點(dian)的運算,GCC編譯器已經(jing)有這(zhe)個庫了,一(yi)(yi)般(ban)(ban)在libgcc里面(mian)。這(zhe)時(shi)根本(ben)不會(hui)使(shi)用(yong)(yong)(yong)(yong)任何浮(fu)點(dian)指(zhi)令,而是采用(yong)(yong)(yong)(yong)常用(yong)(yong)(yong)(yong)的指(zhi)令來模擬浮(fu)點(dian)運算。但使(shi)用(yong)(yong)(yong)(yong)的ARM芯片不支持(chi)硬浮(fu)點(dian)時(shi),可以考慮使(shi)用(yong)(yong)(yong)(yong)這(zhe)個參(can)數(shu)。在使(shi)用(yong)(yong)(yong)(yong)這(zhe)個參(can)數(shu)時(shi),連(lian)接時(shi)一(yi)(yi)般(ban)(ban)會(hui)出現下面(mian)的提(ti)示:

undefined reference to `__aeabi_fdiv'

或者類似(si)的提示,主(zhu)要(yao)因為一(yi)般情況下連接器沒有去主(zhu)動尋找軟浮(fu)點(dian)庫,這(zhe)時(shi)使用(yong)將libgcc庫加入即可。

-mfloat-abi=softfp

-mfloat-abi=hard

這兩個參數都(dou)用來產生硬浮點(dian)指令(ling)(ling),至于產生哪里類型的(de)硬浮點(dian)指令(ling)(ling),需要(yao)由

-mfpu=xxx參數來指令。這兩個參數不(bu)同(tong)的地(di)方是:

-mfloat-abi=softfp生成的(de)代碼(ma)采用(yong)(yong)兼容(rong)軟浮點調用(yong)(yong)接口(即使(shi)用(yong)(yong)-mfloat-abi=soft時的(de)調用(yong)(yong)接口),這樣帶來的(de)好處是:兼容(rong)性和(he)靈活(huo)性。庫可以(yi)(yi)采用(yong)(yong)-mfloat-abi=soft編(bian)譯(yi),而關鍵的(de)應(ying)用(yong)(yong)程(cheng)序可以(yi)(yi)采用(yong)(yong)-mfloat-abi=softfp來編(bian)譯(yi)。特別是在(zai)庫由第三方發布的(de)情況下。

-mfloat-abi=hard生成(cheng)的(de)代碼采用硬(ying)浮點(FPU)調用接口(kou)。這樣要(yao)求所有庫和應(ying)用程序必須采用這同一個參數來編譯,否則連接時會出現接口(kou)不兼容錯誤。

我(wo)們對main.c文件使用硬(ying)件浮點(dian)重(zhong)新編譯:

翻譯成的匯(hui)編代碼如下:

start.s:
        .global _start
        #define USER_MODE 0x10
        _start:
        @ 設置為所有模式都可以訪問協處理器,cortex-A8手冊 3.2.27
        mov r0, #0xfffffff
        mcr p15, 0, r0, c1, c0, 2
        @ 使能NEON and VFP協處理器,NEON and VFP enable bit.
        @ 設置fpexc的30位為1去使能NEON and VFP,cortex-A8 手冊 13.4.3
        ldr r0, =1<<30
        fmxr fpexc, r0
        @設置CPU為user模式
        mov r0,#USER_MODE
        msr cpsr_c,r0
        @跳到main函數
        ldr sp,=0x34000
        bl main
        stop:
        b stop
        main.c:
        int main()
        {
  nbsp;              float f1,f2,f3;
                f1 = 1.24;
                f2 = 1.22;
                f3 = f1 + f2;
                return 0;
        }
        Makefile:
        CC=arm-none-eabi-gcc
        AS=arm-none-eabi-as
        LD=arm-none-eabi-ld
        OBJDUMP=arm-none-eabi-objdump
        RM=rm -rf
        CFLAG=-g -c -mfpu=neon -mfloat-abi=softfp
        ASFLAG=-g -c -mfpu=neon -mfloat-abi=softfp
        OBJ=start.o main.o
        #設置編譯模式
        %.o:%.S
        $(CC) $(ASFLAG) $< -o $@
        %.o:%.c
        $(CC) $(CFLAG) $< -o $@
        all:$(OBJ)
        $(LD) -Ttext=0x20000 $^ -o arm.elf
        $(OBJDUMP) -D arm.elf > arm.dis
        clean:
    &nbsp;   $(RM) *.o arm.dis arm.elf

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)