前言:ARM编译的时候有很多编译选项和浮点功能相关,要真正理解这些编译选项的选择,不仅仅要了解ARM的体系构建的基础知识,可能还需要了解一下ARM的历史。之后,真对这些再考虑到ARM编译选项就比较好理解和记忆了。

1 ARM 的发展历史

ARM的发展历史比较复杂,建议参考wilipedia上的详细说明,本文只是为了说明,编译选项的发展历史。这里简单列举了一下。

1.1 Acorn RISC Machine(简称ARM)

1978年12月5日,物理学家Hermann Hauser和工程师Chris Curry,在英国剑桥创办了CPU公司(Cambridge Processing Unit),主要业务是为当地市场供应电子设备。1979年,CPU公司改名为Acorn计算机公司。80年代中期,Acorn的一个小团队要为他们的下一代计算机挑选合适的处理器,根据他们提供的技术需求,在当时的市场上无法找到合适的处理器,于是Acorn决定自己设计一个处理器。一个小团队仅仅用了18个月就完成了从设计到实现的全过程,这是一台RISC指令集的计算机,叫做Acorn RISC Machine(简称ARM)。后来Acorn公司没落了,而处理器设计部门被分了出来,组成了一家新公司。ARM公司主要设计ARM系列AISC处理器内核,它不生产芯片,只提供 IP核。

1985年第一个基于RISC指令集的ARM芯片是在1985年开始设计的,采用的是典型的32位RISC体系结构,其指令拥有4位的寄存器地址域,可以访问R0-R15这16个寄存器。而其他的寄存器只有在特殊的情况下才可以访问到。

ARM将其技术授权给世界上许多著名的半导体、软件和OEM厂商,每个厂商得到的都是一套独一无二的ARM相关技术及服务。利用这种合伙关系,ARM很快成为许多全球性RISC标准的缔造者。

1.2 ARM(Advanced RISC Machines)

In the late 1980s Apple Computer and VLSI Technology started working with Acorn on newer versions of the ARM core. In 1990, Acorn spun off the design team into a new company named Advanced RISC Machines Ltd.

1990年,ARM公司成立了。在ARM7中,将ARM体系结构完全扩展到32位(原来的ARM处理器只有26位的地址空间),并将主频提升到40MHz,另外还集成了一个8KB的Cache。比较有趣的是,ARM7可以支持一种称为"Thumb"的模式,可以运行新的16位指令。通过引入Thumb模式,只需要付出很少的硬件代价,就可以将代码的密度提升大约25%-35%,并使得应用的运行更为迅速。

1996年,StrongARM SA-110问世了,并成为嵌入式微处理器设计的一个里程碑。StrongARM SA-110可以工作在200MHz,而能耗不到1瓦。在体系结构上,
StrongARM将原来ARM中的三级流水线扩展到五级,在器件工艺上,大量采用了最新的体系结构和器件技术,大大降低了芯片工作时的能耗。1997年,Intel接管了StrongARM

ARM9EJ是ARM9E在Java支持上的增强版本。它采用了类似Thumb的机制,通过很少的硬件代价,使大多数Java虚拟机字节码可以加速执行,更为复杂的Java虚拟机字节码可以通过软件的方式执行。这样,使得Java虚拟机字节码的执行速度提升了大约8倍左右。这对于嵌入式场合的Java应用无疑是极其有效的。

2 ARM架构分类

【案】 ARM7 和 ARMV7是两个不同的概念,ARMV7是ARM的架构版本v7,ARM7是芯片的名称
Architecture Core bit width Cores designed by ARM Holdings Cores designed by third parties Profile References
ARMv1 32[a 1] ARM1      
ARMv2 32[a 1] ARM2, ARM250, ARM3 Amber, STORM Open Soft Core[38]    
ARMv3 32[a 2] ARM6, ARM7      
ARMv4 32[a 2] ARM8 StrongARM, FA526    
ARMv4T 32[a 2] ARM7TDMI, ARM9TDMI, SecurCore SC100      
ARMv5TE 32 ARM7EJ, ARM9E, ARM10E XScale, FA626TE, Feroceon, PJ1/Mohawk    
ARMv6 32 ARM11      
ARMv6-M 32 ARM Cortex-M0, ARM Cortex-M0+,ARM Cortex-M1, SecurCore SC000   Microcontroller  
ARMv7-M 32 ARM Cortex-M3, SecurCore SC300   Microcontroller  
ARMv7E-M 32 ARM Cortex-M4, ARM Cortex-M7   Microcontroller  
ARMv7-R 32 ARM Cortex-R4, ARM Cortex-R5,ARM Cortex-R7, ARM Cortex-R8   Real-time  
ARMv7-A 32 ARM Cortex-A5, ARM Cortex-A7,ARM Cortex-A8, ARM Cortex-A9,ARM Cortex-A12, ARM Cortex-A15,ARM Cortex-A17 Qualcomm Krait, Scorpion, PJ4/Sheeva, Apple Swift Application  
ARMv8-A 32 ARM Cortex-A32   Application  
ARMv8-A 64 ARM Cortex-A35[39], ARM Cortex-A53,ARM Cortex-A57[40], ARM Cortex-A72[41],ARM Cortex-A73[42] X-Gene, Nvidia Project Denver, AMD K12, Apple Cyclone/Typhoon/Twister, Cavium Thunder X,[43][44][45] Qualcomm Kryo Application [46][47]
ARMv8.1-A 64/32 TBA   Application  
ARMv8.2-A 64/32 TBA   Application  
ARMv8-R 32 ARM Cortex-R52   Real-time [48][49][50]
ARMv8-M 32 TBA   Microcontroller [51

3 ARM的命名规则

ARM命名规则:

  第一个数字:系列名称:eg.ARM7、ARM9

  第二个数字:Memory system

  2:带有MMU

  4:带有MPU

  6:无MMU与MPU

  第三个数字:Memory size

  0:标准Cache(4-128k)

  2:减小的Cache

  6:可变的Cache

  第四个字符:T:表示支持Thumb指令集

  D:表示支持片上调试(Debug)

  M:表示内嵌硬件乘法器(Multiplier)

  I :支持片上断点和调试点

  E:表示支持增强型DSP功能

5 NEON 简介

4 浮点数编译选项和ARM的版本

4.1 浮点的主要应用场景

VFP Applications

  • Automotive control applications

    • Powertrain
    • ABS, Traction control & active suspension
  • 3D Graphics
    • Digital consumer products
    • Set-top boxes, games consoles
  • Imaging
    • Laser printers, still digital cameras, digital video cameras
  • Industrial control systems
    • Motion controls

4.2  VFP的架构版本

  1. VFPv1 is obsolete. Details are available on request from ARM.
  2. VFPv2 is an optional extension to the ARM instruction set in the ARMv5TE, ARMv5TEJ and ARMv6 architectures.
  3. VFPv3 is an optional extension to the ARM, Thumb® and ThumbEE instruction sets in the ARMv7-A and ARMv7-R profiles. VFPv3 implementation is with either thirty-two or sixteen double word registers. The terms VFPv3-D32 and VFPv3-D16 distinguish between these two implementation options. Extending VFPv3 uses the half-precision extensions that provide conversion functions in both directions between half-precision floating-point and single-precision floating-point.

5 浮点编译选项汇总讨论

1      浮点类型-mfloat-abi

1.1      选项

-mfloat-abi=soft/softfp/hard
支持3种类型,各类型含义如下:
 soft
不使用硬件浮点单元,gcc使用软浮点库来完成浮点运算。适用于不含FPU的CPU。
 softfp
使用硬浮点单元,会生成硬浮点指令,生成何种类型的硬浮点指令由-mfpu选项指定。调用接口的规则和soft选项一致。
 hard
使用硬浮点单元,生成硬浮点指令。与softfp的区别在于调用接口的规则不同。

1.2  示例

1.2.1 示例代码
float mul(float a, float b)
{
return a*b;
}
1.2.2 soft选项
编译及反汇编命令
arm-linux-gcc -Wall -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=soft -c test.c
arm-linux-objdump -D test.o | less
生成的汇编指令
00000000 <mul>:
0: e92d4800 push {fp, lr}
4: e28db004 add fp, sp, #4
8: e24dd008 sub sp, sp, #8
c: e50b0008 str r0, [fp, #-8]
10: e50b100c str r1, [fp, #-12]
14: e51b0008 ldr r0, [fp, #-8]
18: e51b100c ldr r1, [fp, #-12]
1c: ebfffffe bl 0 <__aeabi_fmul>
20: e1a03000 mov r3, r0
24: e1a00003 mov r0, r3
28: e24bd004 sub sp, fp, #4
2c: e8bd8800 pop {fp, pc}
可以看出是调用__aeabi_fmul接口来进行浮点运算。
1.2.3 softfp选项
编译命令
arm-linux-gcc -Wall -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=vfpv3-d16 -c test.c
生成的汇编指令
00000000 <mul>:
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e24dd00c sub sp, sp, #12
c: e50b0008 str r0, [fp, #-8]
10: e50b100c str r1, [fp, #-12]
14: ed1b7a02 vldr s14, [fp, #-8]
18: ed5b7a03 vldr s15, [fp, #-12]
1c: ee677a27 vmul.f32 s15, s14, s15
20: ee173a90 vmov r3, s15
24: e1a00003 mov r0, r3
28: e28bd000 add sp, fp, #0
2c: e49db004 pop {fp} ; (ldr fp, [sp], #4)
30: e12fff1e bx lr
生成了vxxx的硬浮点指令。并且可以看出和soft一样,都是用r0,r1来传递形参。
1.2.4 hard
编译命令
arm-linux-gcc -Wall -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3-d16 -c test.c
生成的汇编指令
00000000 <mul>:
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e24dd00c sub sp, sp, #12
c: ed0b0a02 vstr s0, [fp, #-8]
10: ed4b0a03 vstr s1, [fp, #-12]
14: ed1b7a02 vldr s14, [fp, #-8]
18: ed5b7a03 vldr s15, [fp, #-12]
1c: ee677a27 vmul.f32 s15, s14, s15
20: eeb00a67 vmov.f32 s0, s15
24: e28bd000 add sp, fp, #0
28: e49db004 pop {fp} ; (ldr fp, [sp], #4)
2c: e12fff1e bx lr
同样生成了硬浮点指令,与softfp的区别在于,这里使用FPU的寄存器s0、s1来传递形参。

2 使用NEON

2.1 选项

-O3 -mfloat-abi=softfp -mfpu=neon -ftree-vectorize
neon可以做浮点运算,有了neon,可以不使用vfp。
为了提升生成的代码性能,应该使用neon intrinsics的方式来写代码。
2.2 示例
普通代码
void NeonTest(int * x, int * y, int * z)
{
int i;
for(i=0;i<200;i++) {
z[i] = x[i] + y[i];
}
}
neon intrinsics格式的代码
#include <arm_neon.h>
void intrinsics(uint32_t *x, uint32_t *y, uint32_t *z)
{
int i;
uint32x4_t x4,y4; // These 128 bit registers will contain 4 values from the x array and 4 values from the y array
uint32x4_t z4; // This 128 bit register will contain the 4 results from the add intrinsic
uint32_t *ptra = x; // pointer to the x array data
uint32_t *ptrb = y; // pointer to the y array data
uint32_t *ptrz = z; // pointer to the z array data
for(i=0; i < 200/4; i++)
{
x4 = vld1q_u32(ptra); // intrinsic to load x4 with 4 values from x
y4 = vld1q_u32(ptrb); // intrinsic to load y4
z4=vaddq_u32(x4,y4); // intrinsic to add z4=x4+y4
vst1q_u32(ptrz, z4); // store the 4 results to z
ptra+=4; // increment pointers
ptrb+=4;
ptrz+=4;
}
}

REF:

1 ARM GCC浮点编译选项

http://blog.csdn.net/jijiagang/article/details/12952681

2 Floating Point

http://www.arm.com/products/processors/technologies/vector-floating-point.php

3 ARM的发展史以及架构解析

http://www.elecfans.com/emb/arm/20160422415359.html

4 ARM简介

http://www.xuebuyuan.com/1444525.html

5 ARM_architecture

https://en.wikipedia.org/wiki/ARM_architecture

[ARM] [基础][编译]ARM的浮点功能历史分类和对应的编译选项相关推荐

  1. ARM基础教程 | ARM 和 x86 的区别

    关注+星标公众号,不错过精彩内容 编排 | strongerHuang 微信公众号 | strongerHuang 首先给大家描述一下计算机的两种花指令集: CISC:Complex Instruct ...

  2. ARM基础教程 | ARM多级流水线的优缺点

    关注+星标公众号,不错过精彩内容 编排 | strongerHuang 微信公众号 | strongerHuang 为什么有些CPU的主频更低,但运算效率却更高呢? 比如:51单片机30M主频,STM ...

  3. ARM基础教程 | ARM与RISC-V架构的区别

    关注+星标公众号,不错过精彩内容 编排 | strongerHuang 微信公众号 | 嵌入式专栏 从2019年开始,RISC-V得到了越来越多的重视,原因有很多,ARM授权费高是关键的因素,下面就来 ...

  4. ARM基础教程 | ARM、Cortex-M与ARMv8-M什么关系?

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | 嵌入式专栏 我们使用的处理器都有一套架构,比如intel 酷睿 i5 属于X86架构,再比如STM32F0是Co ...

  5. arm编程语言基础c,ARM基础:ARM 伪指令详解

    / 4.1 ARM汇编器所支持的伪指令本文引用地址:http://www.eepw.com.cn/article/201611/318753.htm 在ARM汇编语言程序里,有一些特殊指令助记符,这些 ...

  6. ffmpeg arm linux编译,arm linux 移植 ffmpeg 库 + x264 + x265

    背景 Ffmpeg 中带有h264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx264. ...

  7. linux 内核编译arm,如何编译ARM的linux驱动

    在电脑的linux上安装了ARM2440的linux交叉编译器. 现在我按照网上的资料写了个简单的hello驱动. #include #include #include MODULE_LICENSE( ...

  8. ARM基础(5) ARM通讯接口

    设备间进行通信实现得话, 如果把之前得等当成是一个设备得话, 那我们要控制一个灯得话, CPU是不是有一根线接到灯上, 使这个管脚输出 高电频和低电频控制这个灯亮, 控制灯得操作 , 那怎么才能实现通 ...

  9. [ARM]【编译】【实践】 - 浮点编译选项NEON引发的Skia的库Illegal instruction运行错误和解决办法

    前言,ARM编译器选项除了优化系统代码性能外,往往还具备其他一些设定,例如警告级别,和指令集的扩展 本文论述工作中遇到的一个编译开源浏览器chromine遇到的问题,由编译选项引发的可执行文件的Ill ...

最新文章

  1. webSocket详解
  2. Python调用外部程序——os.system()和subprocess.call()
  3. keepalive实验配置
  4. 【转:理论知识】SAP在建工程转固定资产
  5. zookeepr+kafka集群搭建(一)
  6. 给你人生的启迪飞鸽传书
  7. 春运公益片“情满回家路”上线 顺风车等出行方式再被呼吁
  8. oracle ora-14404,分区表的分区表空间不同引起的删除表空间错误
  9. 微信小程序源代码基本文件类型
  10. 【MFC】如何使用MFC?MFC如何编写界面?MFC使用零基础教程
  11. CSS盒子模型、浮动+例子分析
  12. 5+API实现微信分享功能
  13. 数据结构队列顺序循环队列、加入、删除、取头元素
  14. iOS自学-混合编程
  15. uniapp获取手机状态栏和头部导航栏高度(可用于制作头部自定义导航栏)
  16. 将个人微信公众号变成查券返利机器人完美教程分享
  17. 计算机无网络连接,电脑无网络连接怎么办
  18. JDK 21 要来了:已从主线分叉,将成为下一个 LTS 版本!
  19. java 获取 上个月的今天
  20. 如何减少仓库中的拣货和包装错误

热门文章

  1. JavaScript异步编程【下】 -- Generator、Async/await
  2. 十分钟搞定 pandas
  3. C#LeetCode刷题之#203-删除链表中的节点(Remove Linked List Elements)
  4. golang mysql遇到的一些问题记录和解决
  5. HTTPs 相关的东西
  6. java版本-API接口测试框架搭建
  7. zoho配置dmarc_停止[营销]电子邮件反弹! 如何配置SPF,DMARC和DKIM
  8. gitlab定期备份_如何在一分钟内让GitLab为您做定期工作
  9. SAS在金融中的应用五
  10. vb.net 数据集设计器 新增列_SQLPro for MSSQL for Mac(数据库客户端)