ARMアセンブリ中__浮動小数点_操作
6681 ワード
#include
#include
#define INIT_TIMER_VALIABLE \
struct timeval tpstart,tpend; \
float timeuse;
#define START_TIMER gettimeofday(&tpstart,NULL);
#define END_PRINTF_TIMER(name) \
gettimeofday(&tpend,NULL); \
timeuse=(tpend.tv_sec*1000*1000+tpend.tv_usec)-(tpstart.tv_sec*1000*1000+tpstart.tv_usec); \
printf("func :%s:time use(us) %f
",name,timeuse);
float vfp_operate(float f1, float f2)
{
float sum=0;
__asm__ __volatile__(
"vmov s1, %1
"
"vmov s2, %2
"
"fmuls s0, s1, s2
"
"vmov %0, s0
"
:"=r"(sum)
:"r"(f1),"r"(f2)
);
return sum;
}
int main()
{
float f1,f2;
float result;
INIT_TIMER_VALIABLE
printf("input float data1:");
scanf("%f",&f1);
printf("input float data2:");
scanf("%f",&f2);
START_TIMER
result=f1*f2;
END_PRINTF_TIMER("use system function")
printf("result is %f
",result);
START_TIMER
result=vfp_operate(f1,f2);
END_PRINTF_TIMER("use vfp_operate")
printf("result is %f
",result);
}
/*
:
./vfp_helloworld
input float data1:0.125
input float data2:1.684
func :use system function:time use(us) 12.000000
result is 0.210500
func :use system function:time use(us) 5.000000
result is 0.210500
*/
:
:
#include
int main()
{
float f1,f2;
printf("input float data1:");
scanf("%f",&f1);
printf("input float data2:");
scanf("%f",&f2);
printf("float %f x %f =%f
", f1,f2,f1*f2);
}
:( -mfloat-abi=softfp =sofltfp =hard )
arm-none-linux-gnueabi-gcc vfp_helloworld.c -S arm-none-linux-gnueabi-gcc vfp_helloworld.c -S -o vfp_helloworld.asm
-mfloat-abi=softfp -o vfp_helloworld.asm
.cpu arm10tdmi .cpu arm10tdmi
.eabi_attribute 27, 3 .fpu softvfp
.fpu vfp .eabi_attribute 20, 1
.eabi_attribute 20, 1 .eabi_attribute 21, 1
.eabi_attribute 21, 1 .eabi_attribute 23, 3
.eabi_attribute 23, 3 .eabi_attribute 24, 1
.eabi_attribute 24, 1 .eabi_attribute 25, 1
.eabi_attribute 25, 1 .eabi_attribute 26, 2
.eabi_attribute 26, 2 .eabi_attribute 30, 6
.eabi_attribute 30, 6 .eabi_attribute 18, 4
.eabi_attribute 18, 4 .file "vfp_helloworld.c"
.file "vfp_helloworld.c" .section .rodata
.section .rodata .align 2
.align 2 .LC0:
.LC0: .ascii "input float data1:\000"
.ascii "input float data1:\000" .align 2
.align 2 .LC1:
.LC1: .ascii "%f\000"
.ascii "%f\000" .align 2
.align 2 .LC2:
.LC2: .ascii "input float data2:\000"
.ascii "input float data2:\000" .global __aeabi_f2d
.align 2 .global __aeabi_fmul <<
RMのpdfドキュメントの説明
浮動小数点演算をサポートするARMプロセッサカーネルには浮動小数点ハードウェアは含まれていません.浮動小数点アルゴリズムのサポートは、次の2つの方法のいずれかを使用する必要があります.
ソフトウェアでは、浮動小数点ライブラリfplibを使用します.このライブラリには、追加のハードウェアを必要とせずに浮動小数点演算を実行して呼び出す関数があります.『ライブラリガイド』4-2ページのソフトウェア浮動小数点ライブラリfplibを参照してください.
ハードウェアでは、VFPハードウェアコプロセッサを含むARMプロセッサコアを使用して必要な浮動小数点演算を行います.VFPはIEEE浮動小数点を実行するコプロセッサアーキテクチャであり,単精度と二重精度をサポートするが,拡張精度はサポートしない.
Note
実際のプログラミングでは、VFPの浮動小数点演算は、実際にはハードウェア(一般的な実行)とソフトウェア(一般的でない処理と異常の原因)を組み合わせて実行される.VFPサポートを参照してください.
Example 5.2は、浮動小数点アルゴリズムをCで実行する関数であり、浮動小数点アルゴリズムのソフトウェアとハードウェアのサポートの違いを説明する.
Example 5.2. 浮動小数点演算
float foo(float num1, float num2)
{
float temp, temp2;
temp = num1 + num2;
temp2 = num2 * num2;
return temp2-temp;
}
コマンドラインオプションであるcpu 5 TE--fpu softvfpを使用してExample 5.2のCコードをコンパイルすると、コンパイラが生成したマシンコードの逆アセンブリがExample 5.3に示されます.この例では、フローティングアルゴリズムは、__aeabi_fmulのようなライブラリルーチンを呼び出すことによってソフトウェアで実行される.
Example 5.3. ソフトウェアでの浮動小数点演算のサポート
||foo|| PROC
PUSH {r4-r6, lr}
MOV r4, r1
BL __aeabi_fadd <<< MOV r5, r0
MOV r1, r4
MOV r0, r4
BL __aeabi_fmul <<<< MOV r1, r5
POP {r4-r6, lr}
B __aeabi_fsub
ENDP
コマンドラインオプションであるfpu vfpを使用してExample 5.2のCコードをコンパイルすると、コンパイラが生成したマシンコードの逆アセンブリがExample 5.4に示されます.この例では、ハードウェアにおいて、VMUL.F 32などの浮動小数点アルゴリズム命令によって浮動小数点アルゴリズムが実行される.
Example 5.4. ハードウェアでの浮動小数点演算のサポート
||foo|| PROC
VADD.F32 s2, s0, s1
VMUL.F32 s0, s1, s1
VSUB.F32 s0, s0, s2
BX lr
ENDP
実際のプログラミングでは、ハードウェアを使用して浮動小数点アルゴリズムをサポートするコードがよりコンパクトであり、ソフトウェアで浮動小数点アルゴリズムを実行するコードよりも優れた性能を提供する.ただし、浮動小数点アルゴリズムのハードウェアサポートにはVFPコプロセッサが必要です.
デフォルトでは、VFPコプロセッサがある場合、VFP命令が生成されます.VFPコプロセッサがない場合、コンパイラは、浮動小数点演算を実行するためにソフトウェア浮動小数点ライブラリfplibを呼び出すコードを生成します.fplibはCライブラリRealView Development Suite標準配布の構成部分である.