ARM 浮點運算

2021-06-26 09:37:26 字數 3696 閱讀 6702

很多時候我們要處理的資料,不僅僅是整數和字串,還有浮點數即小數。在多**資料處理方面表現的更多。是不是所有的cpu都支援,浮點運算呢?答案:不是。

我們常常聽到贏浮點和軟浮點,這些到底說的是什麼呢?下面我們就來一**竟吧。在這裡我們說的是arm核浮點運算。

(1)硬浮點(hard-float)

編譯器將**直接編譯成硬體浮點協處理器(浮點運算單元fpu)能識別的指令,這些指令在執行的時候arm核直接把它轉給協處理器執行。fpu 通常有一套額外的暫存器來完成浮點引數傳遞和運算。使用實際的硬體浮點運算單元(fpu)會帶來效能的提公升。

(2)軟浮點(soft-float)

編譯器把浮點運算轉成浮點運算的函式呼叫和庫函式呼叫,沒有fpu的指令呼叫,也沒有浮點暫存器的引數傳遞。浮點引數的傳遞也是通過arm暫存器或者堆疊完成。現在的linux系統預設編譯選擇使用hard-float,如果系統沒有任何浮點處理器單元,這就會產生非法指令和異常。因而一般的系統映象都採用軟浮點以相容沒有vfp的處理器。

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

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

例如:我想實現兩個浮點數相加,**如下:

使用gnu arm編譯器翻譯成的部分彙編**如下:

從圖中我們可以知道,預設情況下,編譯器使用的是軟浮點,圖中__aeabi_fadd這個函式是在浮點庫中實現。如果想讓**能正常的執行,還需要在連線的時候靜態連線一下浮點庫。

在這裡我們以乙個完成的案例來說明一下,軟浮點庫的使用方法。

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()

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:

$(rm) *.o arm.dis arm.elf

使用硬體浮點實現浮點運算(hard-float)

使用硬體浮點的時候,我們需要給編譯器傳遞一些引數,讓編譯器編譯出硬體浮點單元處理器能識別的指令。

(1)-mfpu=name

引數-mfpu就是用來指定要產生那種硬體浮點運算指令,常用的右vfp和neon等。

浮點協處理器指令:

arm10 and arm9:

-mfpu=vfp(or vfpv1 or vfpv2)

cortex-a8:

-mfpu=neon

(2) -mfloat-abi=value

undefined reference to `__aeabi_fdiv'

或者類似的提示,主要因為一般情況下聯結器沒有去主動尋找軟浮點庫,這時使用將libgcc庫加入即可。

-mfloat-abi=softfp

-mfloat-abi=hard

這兩個引數都用來產生硬浮點指令,至於產生**型別的硬浮點指令,需要由

-mfpu=***引數來指令。這兩個引數不同的地方是:

-mfloat-abi=softfp生成的**採用相容軟浮點呼叫介面(即使用-mfloat-abi=soft時的呼叫介面),這樣帶來的好處是:相容性和靈活性。庫可以採用-mfloat-abi=soft編譯,而關鍵的應用程式可以採用-mfloat-abi=softfp來編譯。特別是在庫由第三方發布的情況下。

-mfloat-abi=hard生成的**採用硬浮點(fpu)呼叫介面。這樣要求所有庫和應用程式必須採用這同乙個引數來編譯,否則連線時會出現介面不相容錯誤。

我們對main.c檔案使用硬體浮點重新編譯:

翻譯成的彙編**如下:

@ 設定為所有模式都可以訪問協處理器,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()

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:

$(rm) *.o arm.dis arm.elf

ARM 浮點運算

很多時候我們要處理的資料,不僅僅是整數和字串,還有浮點數即小數。在多 資料處理方面表現的更多。是不是所有的cpu都支援,浮點運算呢?答案 不是。我們常常聽到贏浮點和軟浮點,這些到底說的是什麼呢?下面我們就來一 竟吧。在這裡我們說的是arm核浮點運算。1 硬浮點 hard float 編譯器將 直接編...

ARM 浮點運算,軟浮點,硬浮點

很多時候我們要處理的資料,不僅僅是整數和字串,還有浮點數即小數。在多 資料處理方面表現的更多。是不是所有的cpu都支援,浮點運算呢?答案 不是。我們常常聽到贏浮點和軟浮點,這些到底說的是什麼呢?下面我們就來一 竟吧。在這裡我們說的是arm核浮點運算。1 硬浮點 hard float 編譯器將 直接編...

ARM上的浮點運算

使用arm linux gcc 4.3.2編譯必須啟用核心中的use the arm eabi選項 不知道為什麼使用 arm linux gcc 4.3.2.tgz with eabi 86mb 編譯同樣的東西就是出現如下錯誤,感覺可能是busybox 1.14.3的問題,因為使用 arm linu...