ARM上的浮点运算

2024-03-03 16:18
文章标签 arm 浮点运算

本文主要是介绍ARM上的浮点运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.chinaunix.net/uid-22682903-id-1771420.html


这篇文章对最近遇到上的ARM上浮点运算的问题做一个总结。

首先,我们先看一下ARM处理器是如何处理浮点运算的。
交叉编译器在编译的时候,对于浮点运行会预设硬浮点运算FPA(Float Point Architecture),而没有FPA的CPU,比如SAMSUNG S3C2410/S3C2440,会使用FPE(Float Point Emulation 即软浮点),这样在速度上就会遇到极大的限制。也就是说如果有浮点协处理器则交给它去做,如果没有则会产生一个陷阱(trap,处理器响应异常的机制),而我们事先准备好针对浮点指令的陷阱处理程序就可以通过软件来模拟浮点运算指令。

然后,我们解释一下OABI和EABI这两个概念。
/********************************************************************************************/
以下部分转载至http://linux.chinaunix.net/bbs/thread-1143604-1-1.html
1。什么是ABI
ABI,application binary interface (ABI),应用程序二进制接口。
既然是 接口,那就是某两种东西之间的沟通桥梁,此处有这些种情况:
A。应用程序 <-> 操作系统;
B。应用程序 <-> (应用程序所用到的)库
C 。应用程序各个组件之间

类似于API的作用是使得程序的代码间的兼容,ABI目的是使得程序的二进制(级别)的兼容。

2。什么是OABI 和 EABI
OABI中的O,表示“Old”,“Lagacy”,旧的,过时的,OABI就是旧的/老的ABI。
EABI中的E,表示“Embedded”,是一种新的ABI。
EABI有时候也叫做GNU EABI。
OABI和EABI都是专门针对ARM的CPU来说的。

3。EABI的好处 / 为何要用EABI
A。支持软件浮点和硬件实现浮点功能混用
B。系统调用的效率更高
C。后今后的工具更兼容
D。软件浮点的情况下,EABI的软件浮点的效率要比OABI高很多。

4。OABI和EABI的区别
两种ABI在如下方面有区别:
A。调用规则(包括参数如何传递及如何获得返回值)
B。系统调用的数目以及应用程序应该如何去做系统调用
C。目标文件的二进制格式,程序库等
D。结构体中的 填充(padding/packing)和对齐。
E。
OABI:
* ABI flags passed to binutils: -mabi=apcs-gnu -mfpu=fpa
* gcc -dumpmachine: arm-unknown-linux
* objdump -x for compiled binary:

private flags = 2: [APCS-32] [FPA float format] [has entry point]
* "file" on compiled Debian binary:
ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.2.0, dynamically linked (uses shared libs), for GNU/Linux 2.2.0, stripped
* "readelf -h | grep Flags""
Flags: 0x0
EABI:
* ABI flags passed by gcc to binutils: -mabi=aapcs-linux -mfloat-abi=soft -meabi=4
* gcc -dumpmachine: arm-unknown-linux-gnueabi
* objdump -x for compiled binary:
private flags = 4000002: [Version4 EABI] [has entry point]
* "file" on compiled binary (under Debian):
ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.4.17, dynamically linked (uses shared libs), for GNU/Linux 2.4.17, stripped
* "readelf -h | grep Flags""
Flags: 0x4000002, has entry point, Version4 EABI
/********************************************************************************************/
在虚拟机中,运行:arm_v5t_le-gcc -dumpmachine,输出:armv5tl-montavista-linuxeabi;
运行arm_v5t_le-readelf -h EXEC | grep Flags,(注:EXEC代表用交叉编译工具编译的可执行文件名),输出:Flags: 0x4000002, has entry point, Version4 EABI。
上述结果说明当前使用的montavista的编译器是符合EABI标准的。
使用EABI(Embedded Application Binary Interface)则可以对此改善处理,ARM EABI有许多革新之处,其中最突出的改进就是Float Point Performance,它使用Vector Float Point(矢量浮点),因此可以极大提高涉及到浮点运算的程序。

看到这里,之前遇到的一个问题终于弄明白了。之前在Makefile中一直包含一个-mabi=apcs-gnu的参数,而apcs-gnu是OABI的参数,因此将OABI的参数传给符合EABI标准的编译,编译阶段没有报错,但在板上运行时,程序中涉及到浮点数的部分出现了许多莫名的问题。比如printf("%s %f",s,f);这句话输出的浮点数值并不是传给printf的参数,而是一个莫名其妙的数字。解决办法:在Makefile中将“-mabi=apcs-gnu”去掉,重新编译运行,成功!

转载一篇相关文章http://blog.chinaunix.net/u1/38994/showart_2023807.html。
使用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-linux-gcc-4.3.2编译出来的zImage可以使用正常挂在arm-linux-gcc-3.4.1编译器编译出来的动态busybox和库,但是使用 arm-linux-gcc-4.3.2.tgz 编译出来的静态busybox就是会出现下面的错误,开始觉得明显是应用程序出了问题.后来发现原来是内核自己的事情,因为 arm-linux-gcc-4.3.2.tgz使用了EABI方式,所以这就需要内核同样配置EABI编译属性才能支持EABI编译出来的应用程序busybox[luther.gliethttp]

错误原因:没有选择Use the ARM EABI to compile the kernel选项
Kernel Features
[ ] Use the ARM EABI to compile the kernel
解决方法:将它寻上之后自动多出下面一行,这样再次编译的内核就ok了,嘿嘿:)
[*] Use the ARM EABI to compile the kernel 
[*]   Allow old ABI binaries to run with this kernel (EXPERIMENTAL) (NEW) 

ep93xx-rtc ep93xx-rtc: setting system clock to 1970-01-01 00:01:18 UTC (78)
Freeing init memory: 100K
Kernel panic - not syncing: Attempted to kill init!
Backtrace: 
[<c00259c0>] (dump_backtrace+0x0/0x114) from [<c026d674>] (dump_stack+0x18/0x1c)
 r7:c5818000 r6:c5817a40 r5:c5817a40 r4:c03291c4
[<c026d65c>] (dump_stack+0x0/0x1c) from [<c026d6c4>] (panic+0x4c/0x120)
[<c026d678>] (panic+0x0/0x120) from [<c00406e0>] (do_exit+0x70/0x58c)
 r3:c0313004 r2:c5817a40 r1:c5819d0c r0:c02cbdcb
[<c0040670>] (do_exit+0x0/0x58c) from [<c0040c90>] (do_group_exit+0x94/0xc8)
[<c0040bfc>] (do_group_exit+0x0/0xc8) from [<c004ae40>] (get_signal_to_deliver+0x2ec/0x324)
 r7:c5293a74 r6:c5818000 r5:c5819ed4 r4:00000004
[<c004ab54>] (get_signal_to_deliver+0x0/0x324) from [<c0024024>] (do_signal+0x58/0x528)
[<c0023fcc>] (do_signal+0x0/0x528) from [<c0024524>] (do_notify_resume+0x30/0x34)
[<c00244f4>] (do_notify_resume+0x0/0x34) from [<c0021e8c>] (work_pending+0x1c/0x20)

这篇关于ARM上的浮点运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/770175

相关文章

bash: arm-linux-gcc: No such file or directory

ubuntu出故障重装了系统,一直用着的gcc使用不了,提示bash: arm-linux-gcc: No such file or directorywhich找到的命令所在的目录 在google上翻了一阵发现此类问题的帖子不多,后来在Freescale的的LTIB环境配置文档中发现有这么一段:     # Packages required for 64-bit Ubuntu

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte

Cortex-A7:ARM官方推荐的嵌套中断实现机制

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf ARM体系结构与编程第2版 1 前言 Cortex-M系列内核MCU中断硬件原生支持嵌套中断,开发者不需要为了实现嵌套中断而进行额外的工作。但在Cortex-A7中,硬件原生是不支持嵌套中断的,这从Cortex-A7中断向量表中仅为外部中断设置了一个中断向量可以看出。本文介绍ARM官方推荐使用的嵌套中断实现机

ARM 虚拟化介绍

0.目录 文章目录 0.目录1.概述 1.1 Before you begin 2.虚拟化介绍 2.1 虚拟化为什么重要2.2 hypervisors的两种类型2.3 全虚拟化和半虚拟化2.4 虚拟机和虚拟CPUs 3.AArch64中的虚拟化4.stage 2 转换 4.1 什么是stage 2 转换4.2 VMIDs4.3 VMID vs ASID4.4 属性整合和覆盖4.5模拟

SylixOS ARM平台下内存对齐访问

1.内存对齐 1.1     内存对齐概要 现代计算机中内存空间都是按照byte划分的,从理论上讲对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 1.2     内存对齐作用和原因 各个硬件平台对存储空间的处理上有很大的不同。一些平

ubuntu22.04 qemu 安装windows on arm虚拟机

ubuntu22.04 qemu 安装windows on arm虚拟机 iso: https://uupdump.net/ https://massgrave.dev/windows_arm_links vivo driver: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/

arm linux lua移植

lua: lua home 1.下载lua源码 lua下载 lua-5.3.4.tar.gz 2.解压: tar xvf lua-5.3.4.tar.gz 3.修改makefile and luaconf.h $修改 lua-5.3.4/Makefile #INSTALL_TOP= /usr/local INSTALL_TOP= $(shell pwd)/out #修改安装目录(当前目录/o

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、汇编 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一

ARM架构(五)——MMU①

1.MMU基础 1.1 为什么要用MMU,为什么要用虚拟地址? MMU的作用,主要是完成地址的翻译,即虚拟地址到物理地址的转换,无论是main-memory地址(DDR地址),还是IO地址(设备device地址),在开启了MMU的系统中,CPU发起的指令读取、数据读写都是虚拟地址,在ARM Core内部,会先经过MMU将该虚拟地址自动转换成物理地址,然后在将物理地址发送到AXI总线上,完成真正

ARM 伪指令 (26)

LDR 指令: ldr 既是一条伪指令 ,也是一条真正的arm 指令 举例: ldr  r1 , =val 将val的 地址 给到 r1 ldr  r1 , val 将 val 地址的内容给到 r1 . 作用: ldr pc, =32位地址。 这样就可以 实现长跳转。