Mir*_*chi 15 c arm raspberry-pi
我有这个非常简单的代码:
#include <stdio.h>
#include <math.h>
int main()
{
long v = 35;
double app = (double)v;
app /= 100;
app = log10(app);
printf("Calculated log10 %lf\n", app);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码在x86上完美运行,但在arm上不起作用,结果为0.00000.一些想法?
其他信息:
操作系统:linux 3.2.27
我使用ct-ng构建arm工具链:arm-unknown-linux-gnueabi-
libc版本2.13
产量gcc -v:
使用内置规格.COLLECT_GCC = arm-unknown-linux-gnueabi-gcc COLLECT_LTO_WRAPPER =/opt/x-tools/arm-unknown-linux-gnueabi/libexec/gcc/arm-unknown-linux-gnueabi/4.5.1/lto-wrapper目标:手臂-unknown-linux-gnueabi配置:/home/mirko/misc/rasppi-ct-ng-files/.build/src/gcc-4.5.1/configure --build = x86_64-build_unknown-linux-gnu --host = x86_64-build_unknown-linux-gnu --target = arm-unknown-linux-gnueabi --prefix =/opt/x-tools/arm-unknown-linux-gnueabi --with-sysroot =/opt/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi // sys-root --enable-languages = c --disable-multilib --with-pkgversion = crosstool-NG-1.9.3 --enable -__ cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp --with-host-libstdcxx =' - static-libgcc -Wl,-Bstatic,-lstdc ++, - Bdynamic -lm' - with-gmp =/home /mirko/misc/rasppi-ct-ng-files/.build/arm-unknown-linux-gnueabi/build/static --with-mpfr =/home/mirko/misc/rasppi-ct-ng-files/.build/arm-unknown-linux-gnueabi/build/static --with-mpc =/home/mirko/misc/rasppi-ct-ng-files/.build/arm- unknown-linux-gnueabi/build/static --with-ppl =/home/mirko/misc/rasppi-ct-ng-files/.build/arm-unknown-linux-gnueabi/build/static --with-cloog = /home/mirko/misc/rasppi-ct-ng-files/.build/arm-unknown-linux-gnueabi/build/static --with-libelf =/home/mirko/misc/rasppi-ct-ng-files/.build/arm-unknown-linux-gnueabi/build/static --enable-threads = posix --enable-target-optspace --with-local-prefix =/opt/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi // sys-root --disable-nls --enable-symvers = gnu --enable -c99 --enable-long-long线程模型:posix gcc版本4.5.1(crosstool-NG -1.9.3)
aus*_*len 10
ARM Linux发行版上的浮点支持并非易事.因此,您应该使用与您的系统匹配的工具链,即操作系统和硬件,并使用正确的编译开关.
首先需要了解ARM的调用约定,即关于"调用函数时如何传递参数?" .ARM是RISC架构,只能在寄存器上工作.没有指令直接操作内存.如果需要更改内存中的值,首先需要将其加载到寄存器中,修改它,然后需要将其存储在内存中.
当你调用一个函数时,你可能需要向它传递参数,你可以将参数放在堆栈(内存)上,但由于ARM只能使用寄存器,所以你的函数可能会先将它们加载回寄存器.为了避免这种浪费,ARM调用约定使用寄存器来传递参数.但是,由于ARM具有有限数量的寄存器,因此调用约定还要求您仅对前四个参数使用前四个(r0-r3)寄存器,其余仍必须使用堆栈来传递.
第二件事是早期的ARM内核没有任何浮点支持,操作在软件中实现.(这仍然是gcc的支持-mfloat-abi=soft.)
我们可以通过以下代码片段轻松演示这意味着什么.
float pi2(float a) {
return a * 3.14f;
}
Run Code Online (Sandbox Code Playgroud)
编译这个via -c -O3 -mfloat-abi=soft和obdumping给了我们
00000000 <pi2>:
0: f24f 51c3 movw r1, #62915 ; 0xf5c3
4: b508 push {r3, lr}
6: f2c4 0148 movt r1, #16456 ; 0x4048
a: f7ff fffe bl 0 <__aeabi_fmul>
e: bd08 pop {r3, pc}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的(实际上它是不可见的:))pi2在得到它的参数r0,填充pi constant上r1,并使用__aeabi_fmul繁殖那些和返回结果r0.由于__aeabi_fmul也使用相同的调用约定,因此详细信息r0不可见.我们所有的功能都填充r1并委托给它__aeabi_fmul.
当浮动硬件支持添加到ARM时(再次因为架构风格),它带有自己的一组寄存器(s0,s1,...).
如果我们使用-c -O3 -mfloat-abi=softfp和转储编译相同的代码片段,我们得到
00000000 <pi2>:
0: eddf 7a04 vldr s15, [pc, #16] ; 14 <pi2+0x14>
4: ee07 0a10 vmov s14, r0
8: ee27 7a27 vmul.f32 s14, s14, s15
c: ee17 0a10 vmov r0, s14
10: 4770 bx lr
12: bf00 nop
14: 4048f5c3 .word 0x4048f5c3
Run Code Online (Sandbox Code Playgroud)
正如你可以看到现在编译器不建立一个呼叫__aeabi_fmul,而是它创造了vmul.f32它移动位于争吵后指令r0到s14并填充3.14上s15.在乘法指令之后,它会将结果移s14回到可用状态,r0 因为此函数的任何调用者都会因为调用约定而期望它.
现在,如果您认为pi2某些第三方提供给您的库,您可以理解soft和softfp实现对您执行相同的操作,您可以互换使用它们.如果系统为您提供它们,您不关心您的应用程序是否在具有硬件浮点支持的系统上运行.这对于保持旧软件在新硬件上运行非常有用.
然而,在保持兼容性的同时,这种方法引入了在ARM寄存器和FP寄存器之间移动值的开销.这显然会影响性能并通过一个新的调用约定hard来解决gcc.这个新的约定规定,如果你的函数中有浮点参数,你可以利用与正常值交错的浮点寄存器,以及浮点寄存器中的浮点值s0.
再次,如果我们编译我们的代码片段-c -O3 -mfloat-abi=hard和转储我们得到
00000000 <pi2>:
0: eddf 7a02 vldr s15, [pc, #8] ; c <pi2+0xc>
4: ee20 0a27 vmul.f32 s0, s0, s15
8: 4770 bx lr
a: bf00 nop
c: 4048f5c3 .word 0x4048f5c3
Run Code Online (Sandbox Code Playgroud)
你可以看到没有寄存器被移动.参数pi2被传递s0,编译器生成的代码来填充3.14的s15,并使用vmul.f32 s0, s0, s15得到我们想要的结果s0.
这个新约定的一个大问题是,当您改进编译器生成的代码时,您会彻底破坏兼容性.您不能指望使用hard约定构建soft/softfp的应用程序可以使用为其构建的库,而为softfp构建的应用程序将无法与为hard构建的库一起使用.
有关调用约定的更多信息,请查看ARM的网站.
| 归档时间: |
|
| 查看次数: |
1379 次 |
| 最近记录: |